summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2019-11-10 03:44:32 +0000
committerXin LI <delphij@FreeBSD.org>2019-11-10 03:44:32 +0000
commit4ef4bf0189e5e736a37f9ead9beaaa8e1cd1f9fb (patch)
tree0b82394b9b244b8f3a588afe3b96177c08ff98eb /src
parentad1ba6e1e032f79d03b9a6e2c714de84d1911b3a (diff)
Notes
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.in9
-rw-r--r--src/apprentice.c294
-rw-r--r--src/apptype.c12
-rw-r--r--src/ascmagic.c84
-rw-r--r--src/asprintf.c6
-rw-r--r--src/buffer.c17
-rw-r--r--src/cdf.c171
-rw-r--r--src/cdf.h6
-rw-r--r--src/cdf_time.c28
-rw-r--r--src/compress.c298
-rw-r--r--src/der.c37
-rw-r--r--src/dprintf.c6
-rw-r--r--src/elfclass.h18
-rw-r--r--src/encoding.c79
-rw-r--r--src/file.c47
-rw-r--r--src/file.h41
-rw-r--r--src/fmtcheck.c2
-rw-r--r--src/fsmagic.c37
-rw-r--r--src/funcs.c115
-rw-r--r--src/getopt_long.c12
-rw-r--r--src/is_json.c462
-rw-r--r--src/is_tar.c15
-rw-r--r--src/magic.c105
-rw-r--r--src/magic.h.in4
-rw-r--r--src/mygetopt.h2
-rw-r--r--src/print.c42
-rw-r--r--src/readcdf.c57
-rw-r--r--src/readelf.c301
-rw-r--r--src/readelf.h8
-rw-r--r--src/seccomp.c15
-rw-r--r--src/softmagic.c469
-rw-r--r--src/vasprintf.c12
33 files changed, 1830 insertions, 985 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index bbd3f5016d5c3..2fbefdbfcb5b3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,14 +8,14 @@ AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"'
AM_CFLAGS = $(CFLAG_VISIBILITY) @WARNINGS@
libmagic_la_SOURCES = buffer.c magic.c apprentice.c softmagic.c ascmagic.c \
- encoding.c compress.c is_tar.c readelf.c print.c fsmagic.c \
+ encoding.c compress.c is_json.c is_tar.c readelf.c print.c fsmagic.c \
funcs.c file.h readelf.h tar.h apptype.c der.c der.h \
file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h
libmagic_la_LDFLAGS = -no-undefined -version-info 1:0:0
if MINGW
MINGWLIBS = -lgnurx -lshlwapi
else
-MINGWLIBS =
+MINGWLIBS =
endif
libmagic_la_LIBADD = $(LTLIBOBJS) $(MINGWLIBS)
diff --git a/src/Makefile.in b/src/Makefile.in
index afa7bfa061eb3..29567c4702808 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -136,9 +136,9 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libmagic_la_DEPENDENCIES = $(LTLIBOBJS) $(am__DEPENDENCIES_1)
am_libmagic_la_OBJECTS = buffer.lo magic.lo apprentice.lo softmagic.lo \
- ascmagic.lo encoding.lo compress.lo is_tar.lo readelf.lo \
- print.lo fsmagic.lo funcs.lo apptype.lo der.lo cdf.lo \
- cdf_time.lo readcdf.lo
+ ascmagic.lo encoding.lo compress.lo is_json.lo is_tar.lo \
+ readelf.lo print.lo fsmagic.lo funcs.lo apptype.lo der.lo \
+ cdf.lo cdf_time.lo readcdf.lo
libmagic_la_OBJECTS = $(am_libmagic_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -343,7 +343,7 @@ nodist_include_HEADERS = magic.h
AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"'
AM_CFLAGS = $(CFLAG_VISIBILITY) @WARNINGS@
libmagic_la_SOURCES = buffer.c magic.c apprentice.c softmagic.c ascmagic.c \
- encoding.c compress.c is_tar.c readelf.c print.c fsmagic.c \
+ encoding.c compress.c is_json.c is_tar.c readelf.c print.c fsmagic.c \
funcs.c file.h readelf.h tar.h apptype.c der.c der.h \
file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h
@@ -515,6 +515,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsmagic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funcs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/is_json.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/is_tar.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/magic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@
diff --git a/src/apprentice.c b/src/apprentice.c
index ea8d0b222e0a8..eca3ae06af99e 100644
--- a/src/apprentice.c
+++ b/src/apprentice.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.283 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -40,9 +40,7 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef HAVE_STDDEF_H
#include <stddef.h>
-#endif
#include <string.h>
#include <assert.h>
#include <ctype.h>
@@ -51,20 +49,13 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
#include <sys/mman.h>
#endif
#include <dirent.h>
-#if defined(HAVE_LIMITS_H)
#include <limits.h>
-#endif
-#ifndef SSIZE_MAX
-#define MAXMAGIC_SIZE ((ssize_t)0x7fffffff)
-#else
-#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
@@ -83,15 +74,15 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 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
#define MAP_TYPE_MMAP 2
struct magic_entry {
- struct magic *mp;
+ struct magic *mp;
uint32_t cont_count;
uint32_t max_count;
};
@@ -126,7 +117,7 @@ private int apprentice_1(struct magic_set *, const char *, int);
private size_t apprentice_magic_strength(const struct magic *);
private int apprentice_sort(const void *, const void *);
private void apprentice_list(struct mlist *, int );
-private struct magic_map *apprentice_load(struct magic_set *,
+private struct magic_map *apprentice_load(struct magic_set *,
const char *, int);
private struct mlist *mlist_alloc(void);
private void mlist_free(struct mlist *);
@@ -300,12 +291,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" */
@@ -340,7 +340,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
@@ -351,7 +351,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;
}
@@ -437,8 +437,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;
}
@@ -451,7 +451,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
#ifndef COMPILE_ONLY
map = apprentice_map(ms, fn);
- if (map == (struct magic_map *)-1)
+ if (map == RCAST(struct magic_map *, -1))
return -1;
if (map == NULL) {
if (ms->flags & MAGIC_CHECK)
@@ -503,7 +503,7 @@ file_ms_alloc(int flags)
struct magic_set *ms;
size_t i, len;
- if ((ms = CAST(struct magic_set *, calloc((size_t)1,
+ if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u),
sizeof(struct magic_set)))) == NULL)
return NULL;
@@ -582,6 +582,14 @@ mlist_alloc(void)
}
private void
+mlist_free_one(struct mlist *ml)
+{
+ if (ml->map)
+ apprentice_unmap(CAST(struct magic_map *, ml->map));
+ free(ml);
+}
+
+private void
mlist_free(struct mlist *mlist)
{
struct mlist *ml, *next;
@@ -589,14 +597,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));
- free(ml);
- if (ml == mlist)
- break;
+ for (ml = mlist->next; ml != mlist; ml = next) {
+ next = ml->next;
+ mlist_free_one(ml);
}
+ mlist_free_one(mlist);
}
#ifndef COMPILE_ONLY
@@ -826,7 +831,7 @@ typesize(int type)
case FILE_LEDOUBLE:
return 8;
default:
- return (size_t)~0;
+ return CAST(size_t, ~0);
}
}
@@ -836,8 +841,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 */
@@ -880,7 +886,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;
@@ -896,6 +902,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;
@@ -943,9 +951,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;
@@ -965,6 +970,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.
@@ -974,7 +982,7 @@ apprentice_magic_strength(const struct magic *m)
return val;
}
-/*
+/*
* Sort callback for sorting entries by "strength" (basically length)
*/
private int
@@ -992,7 +1000,7 @@ apprentice_sort(const void *a, const void *b)
return 1;
}
-/*
+/*
* Shows sorted patterns list in the order which is used for the matching
*/
private void
@@ -1088,12 +1096,12 @@ set_test_type(struct magic *mstart, struct magic *m)
mstart->flag |= BINTEST;
if (mstart->str_flags & STRING_TEXTTEST)
mstart->flag |= TEXTTEST;
-
+
if (mstart->flag & (TEXTTEST|BINTEST))
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
@@ -1174,7 +1182,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;
@@ -1227,7 +1235,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));
}
@@ -1253,10 +1261,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");
}
@@ -1280,7 +1288,7 @@ set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
file_magwarn(ms,
"level 0 \"default\" did not sort last");
}
- return;
+ return;
}
}
}
@@ -1387,12 +1395,14 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
filearr[files++] = mfn;
}
closedir(dir);
- qsort(filearr, files, sizeof(*filearr), cmpstrp);
- for (i = 0; i < files; i++) {
- load_1(ms, action, filearr[i], &errs, mset);
- free(filearr[i]);
+ if (filearr) {
+ qsort(filearr, files, sizeof(*filearr), cmpstrp);
+ for (i = 0; i < files; i++) {
+ load_1(ms, action, filearr[i], &errs, mset);
+ free(filearr[i]);
+ }
+ free(filearr);
}
- free(filearr);
} else
load_1(ms, action, fn, &errs, mset);
if (errs)
@@ -1450,12 +1460,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:
@@ -1472,7 +1482,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:
@@ -1489,7 +1499,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:
@@ -1616,7 +1626,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;
@@ -1674,7 +1684,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;
@@ -1700,7 +1710,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);
@@ -1714,7 +1724,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':
@@ -1796,7 +1806,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)
@@ -1833,7 +1843,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
*/
while (*l == '>') {
++l; /* step over */
- cont_level++;
+ cont_level++;
}
#ifdef ENABLE_CONDITIONALS
if (cont_level == 0 || cont_level > last_cont_level)
@@ -1851,7 +1861,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,
@@ -1864,7 +1874,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++];
@@ -1910,7 +1920,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);
@@ -2008,8 +2018,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,
@@ -2018,7 +2028,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
}
l = t;
}
- if (*l++ != ')' ||
+ if (*l++ != ')' ||
((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@@ -2043,7 +2053,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
/*
* Try it as a keyword type prefixed by "u"; match what
* follows the "u". If that fails, try it as an SUS
- * integer type.
+ * integer type.
*/
m->type = get_type(type_tbl, l + 1, &l);
if (m->type == FILE_INVALID) {
@@ -2072,7 +2082,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;
}
@@ -2083,7 +2094,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
/* Not found - try it as a special keyword. */
m->type = get_type(special_tbl, l, &l);
}
-
+
if (m->type == FILE_INVALID) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "type `%s' invalid", l);
@@ -2130,7 +2141,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
* anything if mask = 0 (unless you have a better idea)
*/
EATAB;
-
+
switch (*l) {
case '>':
case '<':
@@ -2162,8 +2173,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;
}
@@ -2177,7 +2188,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
/*
* TODO finish this macro and start using it!
- * #define offsetcheck {if (offset > ms->bytes_max -1)
+ * #define offsetcheck {if (offset > ms->bytes_max -1)
* magwarn("offset too big"); }
*/
@@ -2260,11 +2271,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);
@@ -2295,9 +2306,9 @@ 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;
- }
+ }
if (*m->desc == '\0') {
file_magwarn(ms, "Current entry does not yet have a "
@@ -2316,7 +2327,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)
@@ -2418,7 +2429,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; \
@@ -2434,7 +2445,7 @@ check_format_type(const char *ptr, int type, const char **estr)
if (*ptr++ != 'l')
goto invalid;
}
-
+
switch (*ptr++) {
#ifdef STRICT_FORMAT /* "long" formats are int formats for us */
/* so don't accept the 'l' modifier */
@@ -2452,7 +2463,7 @@ check_format_type(const char *ptr, int type, const char **estr)
default:
goto invalid;
}
-
+
/*
* Don't accept h and hh modifiers. They make writing
* magic entries more complicated, for very little benefit
@@ -2508,7 +2519,7 @@ check_format_type(const char *ptr, int type, const char **estr)
default:
goto invalid;
}
-
+
case FILE_FMT_FLOAT:
case FILE_FMT_DOUBLE:
if (*ptr == '-')
@@ -2527,30 +2538,30 @@ check_format_type(const char *ptr, int type, const char **estr)
case 'g':
case 'G':
return 0;
-
+
default:
goto invalid;
}
-
+
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++;
}
-
+
switch (*ptr++) {
case 's':
return 0;
default:
goto invalid;
}
-
+
default:
/* internal error */
abort();
@@ -2561,7 +2572,7 @@ toolong:
*estr = "too long";
return -1;
}
-
+
/*
* Check that the optional printf format in description matches
* the type of the magic.
@@ -2584,7 +2595,7 @@ check_format(struct magic_set *ms, struct magic *m)
if (m->type >= file_nformats) {
file_magwarn(ms, "Internal error inconsistency between "
- "m->type and format strings");
+ "m->type and format strings");
return -1;
}
if (file_formats[m->type] == FILE_FMT_NONE) {
@@ -2604,7 +2615,7 @@ check_format(struct magic_set *ms, struct magic *m)
file_names[m->type], m->desc);
return -1;
}
-
+
for (; *ptr; ptr++) {
if (*ptr == '%') {
file_magwarn(ms,
@@ -2617,9 +2628,9 @@ check_format(struct magic_set *ms, struct magic *m)
return 0;
}
-/*
- * Read a numeric value from a pointer, into the value union of a magic
- * pointer, according to the magic type. Update the string pointer to point
+/*
+ * Read a numeric value from a pointer, into the value union of a magic
+ * pointer, according to the magic type. Update the string pointer to point
* just after the number read. Return 0 for success, non-zero for failure.
*/
private int
@@ -2685,7 +2696,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);
@@ -2694,24 +2705,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;
@@ -2751,7 +2762,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);
@@ -2775,8 +2786,8 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
/*FALLTHROUGH*/
default:
if (warn) {
- if (isprint((unsigned char)c)) {
- /* Allow escaping of
+ if (isprint(CAST(unsigned char, c))) {
+ /* Allow escaping of
* ``relations'' */
if (strchr("<>&^=!", c) == NULL
&& (m->type != FILE_REGEX ||
@@ -2813,7 +2824,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':
@@ -2865,7 +2876,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 */
@@ -2881,18 +2892,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;
}
@@ -2901,9 +2912,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';
@@ -2981,7 +2992,7 @@ eatsize(const char **p)
{
const char *l = *p;
- if (LOWCASE(*l) == 'u')
+ if (LOWCASE(*l) == 'u')
l++;
switch (LOWCASE(*l)) {
@@ -3052,17 +3063,17 @@ apprentice_map(struct magic_set *ms, const char *fn)
file_error(ms, errno, "cannot stat `%s'", dbname);
goto error;
}
- if (st.st_size < 8 || st.st_size > MAXMAGIC_SIZE) {
+ if (st.st_size < 8 || st.st_size > maxoff_t()) {
file_error(ms, 0, "file `%s' is too %s", dbname,
st.st_size < 8 ? "small" : "large");
goto error;
}
- map->len = (size_t)st.st_size;
+ map->len = CAST(size_t, st.st_size);
#ifdef QUICK
map->type = MAP_TYPE_MMAP;
- if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
+ if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) {
file_error(ms, errno, "cannot map `%s'", dbname);
goto error;
}
@@ -3082,11 +3093,11 @@ apprentice_map(struct magic_set *ms, const char *fn)
fd = -1;
if (check_buffer(ms, map, dbname) != 0) {
- rv = (struct magic_map *)-1;
+ rv = RCAST(struct magic_map *, -1);
goto error;
}
#ifdef QUICK
- if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) {
+ if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) {
file_error(ms, errno, "cannot mprotect `%s'", dbname);
goto error;
}
@@ -3130,7 +3141,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",
@@ -3179,10 +3190,10 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
dbname = mkdbname(ms, fn, 1);
- if (dbname == NULL)
+ if (dbname == NULL)
goto out;
- if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
+ if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
{
file_error(ms, errno, "cannot open `%s'", dbname);
goto out;
@@ -3192,14 +3203,14 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
hdr.h[1] = VERSIONNO;
memcpy(hdr.h + 2, map->nmagic, nm);
- if (write(fd, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
+ if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) {
file_error(ms, errno, "error writing `%s'", dbname);
goto out2;
}
for (i = 0; i < MAGIC_SETS; i++) {
len = m * map->nmagic[i];
- if (write(fd, map->magic[i], len) != (ssize_t)len) {
+ if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) {
file_error(ms, errno, "error writing `%s'", dbname);
goto out2;
}
@@ -3245,7 +3256,8 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
q++;
/* Compatibility with old code that looked in .mime */
if (ms->flags & MAGIC_MIME) {
- if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
+ if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext)
+ < 0)
return NULL;
if (access(buf, R_OK) != -1) {
ms->flags &= MAGIC_MIME_TYPE;
@@ -3253,7 +3265,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
}
free(buf);
}
- if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
+ if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0)
return NULL;
/* Compatibility with old code that looked in .mime */
@@ -3280,8 +3292,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;
@@ -3294,8 +3306,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];
@@ -3310,8 +3322,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];
@@ -3341,9 +3353,9 @@ private void
bs1(struct magic *m)
{
m->cont_level = swap2(m->cont_level);
- m->offset = swap4((uint32_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_STRING(m->type)) {
m->str_range = swap4(m->str_range);
m->str_flags = swap4(m->str_flags);
@@ -3354,7 +3366,7 @@ bs1(struct magic *m)
}
}
-protected size_t
+protected size_t
file_pstring_length_size(const struct magic *m)
{
switch (m->str_flags & PSTRING_LEN) {
@@ -3375,7 +3387,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) {
diff --git a/src/apptype.c b/src/apptype.c
index fcd764e49a441..1bb33e41c27a9 100644
--- a/src/apptype.c
+++ b/src/apptype.c
@@ -1,15 +1,15 @@
/*
* Adapted from: apptype.c, Written by Eberhard Mattes and put into the
* public domain
- *
+ *
* Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
* searches.
- *
+ *
* 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com"
* (other than an OS/2 exe or Win exe with this name). Eberhard Mattes
* remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very
* bug ridden) Win Emacs as "OS/2 executable".
- *
+ *
* 3. apptype() uses the filename if given, otherwise a tmp file is created with
* the contents of buf. If buf is not the complete file, apptype can
* incorrectly identify the exe type. The "-z" option of "file" is the reason
@@ -18,16 +18,16 @@
/*
* amai: Darrel Hankerson did the changes described here.
- *
+ *
* It remains to check the validity of comments (2.) since it's referred to an
* "old" OS/2 version.
- *
+ *
*/
#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>
diff --git a/src/ascmagic.c b/src/ascmagic.c
index 2d1abe543e603..624ac90b1f1c2 100644
--- a/src/ascmagic.c
+++ b/src/ascmagic.c
@@ -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$",
@@ -324,42 +346,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;
}
diff --git a/src/asprintf.c b/src/asprintf.c
index 30852d2b3b007..2d14e8074f23d 100644
--- a/src/asprintf.c
+++ b/src/asprintf.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -29,7 +29,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: asprintf.c,v 1.4 2010/07/21 16:47:17 christos Exp $")
+FILE_RCSID("@(#)$File: asprintf.c,v 1.5 2018/09/09 20:33:28 christos Exp $")
#endif
int asprintf(char **ptr, const char *fmt, ...)
diff --git a/src/buffer.c b/src/buffer.c
index 5f76b80d282cb..6d8967d2fa73d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -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"
@@ -37,10 +37,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 struct stat *st, const void *data,
+ size_t len)
{
b->fd = fd;
- if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
+ if (st)
+ memcpy(&b->st, st, sizeof(b->st));
+ else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
memset(&b->st, 0, sizeof(b->st));
b->fbuf = data;
b->flen = len;
@@ -61,13 +64,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 = malloc(b->elen)) == NULL)
goto out;
@@ -79,6 +82,6 @@ buffer_fill(const struct buffer *bb)
return 0;
out:
- b->elen = (size_t)~0;
+ b->elen = CAST(size_t, ~0);
return -1;
}
diff --git a/src/cdf.c b/src/cdf.c
index aad68cd0a33cb..556a3ff868098 100644
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -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>
@@ -47,9 +47,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
@@ -68,11 +66,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 ? \
@@ -90,7 +91,8 @@ static void *
cdf_malloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), size_t n)
{
- DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
+ DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
+ file, line, __func__, n));
return malloc(n);
}
@@ -99,7 +101,8 @@ static void *
cdf_realloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), void *p, size_t n)
{
- DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
+ DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
+ file, line, __func__, n));
return realloc(p, n);
}
@@ -108,7 +111,8 @@ static void *
cdf_calloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), size_t n, size_t u)
{
- DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u));
+ DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %"
+ SIZE_T_FORMAT "u\n", file, line, __func__, n, u));
return calloc(n, u);
}
@@ -119,8 +123,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;
@@ -133,8 +137,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];
@@ -149,8 +153,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];
@@ -215,15 +219,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
@@ -256,15 +262,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);
}
@@ -321,11 +328,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 %"
@@ -338,23 +345,23 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
static ssize_t
cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
{
- size_t siz = (size_t)off + len;
+ size_t siz = CAST(size_t, off + len);
- if ((off_t)(off + len) != (off_t)siz)
+ if (CAST(off_t, off + len) != CAST(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)
goto out;
- if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
+ if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len))
return -1;
- return (ssize_t)len;
+ return CAST(ssize_t, len);
out:
errno = EINVAL;
return -1;
@@ -366,7 +373,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, (off_t)0, buf, sizeof(buf)) == -1)
+ if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1)
return -1;
cdf_unpack_header(h, buf);
cdf_swap_header(h);
@@ -400,7 +407,7 @@ cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
size_t ss = CDF_SEC_SIZE(h);
size_t pos = CDF_SEC_POS(h, id);
assert(ss == len);
- return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
+ return cdf_read(info, CAST(off_t, pos), RCAST(char *, buf) + offs, len);
}
ssize_t
@@ -416,8 +423,8 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
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;
@@ -460,7 +467,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;
}
@@ -477,27 +484,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;
@@ -516,7 +525,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:"));
@@ -536,7 +545,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));
@@ -547,7 +556,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
@@ -564,7 +573,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);
@@ -583,7 +592,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;
@@ -591,7 +600,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:
@@ -610,7 +619,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);
@@ -629,11 +638,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:
@@ -664,7 +673,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;
@@ -685,7 +694,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;
}
@@ -693,7 +703,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++)
@@ -718,7 +728,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));
@@ -737,11 +747,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:
@@ -791,7 +801,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;
}
@@ -859,7 +869,7 @@ cdf_offset(const void *p, size_t l)
}
static const uint8_t *
-cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
+cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
const uint8_t *p, const uint8_t *e, size_t i)
{
size_t tail = (i << 1) + 1;
@@ -874,7 +884,7 @@ cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
__LINE__) == -1)
return NULL;
ofs = CDF_GETUINT32(p, tail);
- q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
+ q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
ofs - 2 * sizeof(uint32_t)));
if (q < p) {
@@ -896,8 +906,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 *,
@@ -922,7 +932,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);
@@ -1065,10 +1075,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++;
@@ -1108,8 +1118,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)
@@ -1260,28 +1271,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);
@@ -1293,7 +1304,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;
}
diff --git a/src/cdf.h b/src/cdf.h
index f2df8306b17d3..2f7e554b71809 100644
--- a/src/cdf.h
+++ b/src/cdf.h
@@ -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;
@@ -272,7 +272,7 @@ typedef struct {
typedef struct {
uint16_t ce_namlen;
uint32_t ce_num;
- uint64_t ce_timestamp;
+ uint64_t ce_timestamp;
uint16_t ce_name[256];
} cdf_catalog_entry_t;
diff --git a/src/cdf_time.c b/src/cdf_time.c
index 2bdcd2a7f7a8a..e4eea4c737f39 100644
--- a/src/cdf_time.c
+++ b/src/cdf_time.c
@@ -27,7 +27,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>
@@ -56,7 +56,7 @@ cdf_getdays(int year)
for (y = CDF_BASE_YEAR; y < year; y++)
days += isleap(y) + 365;
-
+
return days;
}
@@ -68,7 +68,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;
@@ -77,7 +77,7 @@ cdf_getday(int year, int days)
return days;
}
-/*
+/*
* Return the 0...11 month number.
*/
static int
@@ -85,14 +85,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
@@ -108,22 +108,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;
@@ -172,7 +172,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;
}
diff --git a/src/compress.c b/src/compress.c
index 5d565d56089ec..95e42a24dd522 100644
--- a/src/compress.c
+++ b/src/compress.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -29,13 +29,13 @@
* compress routines:
* zmagic() - returns 0 if not recognized, uncompresses and prints
* information if recognized
- * uncompress(method, old, n, newch) - uncompress old into new,
+ * uncompress(method, old, n, newch) - uncompress old into new,
* using method, return sizeof new
*/
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.107 2018/04/28 18:48:22 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.121 2019/05/07 02:27:11 christos Exp $")
#endif
#include "magic.h"
@@ -47,12 +47,10 @@ FILE_RCSID("@(#)$File: compress.c,v 1.107 2018/04/28 18:48:22 christos Exp $")
#include <errno.h>
#include <ctype.h>
#include <stdarg.h>
-#ifdef HAVE_SIGNAL_H
#include <signal.h>
-# ifndef HAVE_SIG_T
+#ifndef HAVE_SIG_T
typedef void (*sig_t)(int);
-# endif /* HAVE_SIG_T */
-#endif
+#endif /* HAVE_SIG_T */
#if !defined(__MINGW32__) && !defined(WIN32)
#include <sys/ioctl.h>
#endif
@@ -62,10 +60,17 @@ typedef void (*sig_t)(int);
#if defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif
+
#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
#define BUILTIN_DECOMPRESS
#include <zlib.h>
#endif
+
+#if defined(HAVE_BZLIB_H)
+#define BUILTIN_BZLIB
+#include <bzlib.h>
+#endif
+
#ifdef DEBUG
int tty = -1;
#define DPRINTF(...) do { \
@@ -137,30 +142,34 @@ 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
};
@@ -170,7 +179,7 @@ private const struct {
private ssize_t swrite(int, const void *, size_t);
#if HAVE_FORK
-private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
+private size_t ncompr = __arraycount(compr);
private int uncompressbuf(int, size_t, size_t, const unsigned char *,
unsigned char **, size_t *);
#ifdef BUILTIN_DECOMPRESS
@@ -179,6 +188,11 @@ 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 *, ...)
__attribute__((__format__(__printf__, 3, 4)));
private const char *methodname(size_t);
@@ -210,18 +224,14 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
int urv, prv, rv = 0;
int mime = ms->flags & MAGIC_MIME;
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;
-#ifdef HAVE_SIGNAL_H
- sig_t osigpipe;
-#endif
+ 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)
@@ -236,10 +246,20 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, 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:
@@ -247,7 +267,7 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
if (urv == ERRDATA)
prv = format_decompression_error(ms, i, newbuf);
else
- prv = file_buffer(ms, -1, name, newbuf, nsz);
+ prv = file_buffer(ms, -1, NULL, name, newbuf, nsz);
if (prv == -1)
goto error;
rv = 1;
@@ -264,8 +284,11 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, 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, -1, 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) {
free(rbuf);
@@ -289,9 +312,9 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, 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);
+
free(newbuf);
ms->flags |= MAGIC_COMPRESS;
DPRINTF("Zmagic returns %d\n", rv);
@@ -367,7 +390,7 @@ sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
(void)ioctl(fd, FIONREAD, &t);
}
- if (t > 0 && (size_t)t < n) {
+ if (t > 0 && CAST(size_t, t) < n) {
n = t;
rn = n;
}
@@ -411,7 +434,9 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
#else
{
int te;
+ mode_t ou = umask(0);
tfd = mkstemp(buf);
+ (void)umask(ou);
te = errno;
(void)unlink(buf);
errno = te;
@@ -423,11 +448,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;
}
@@ -452,7 +477,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
return -1;
}
(void)close(tfd);
- if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
+ if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) {
file_badseek(ms);
return -1;
}
@@ -509,7 +534,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
int rc;
z_stream z;
- if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
+ if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
return makeerror(newch, n, "No buffer, %s", strerror(errno));
z.next_in = CCAST(Bytef *, old);
@@ -529,18 +554,18 @@ 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;
-
+
/* let's keep the nul-terminate tradition */
(*newch)[*n] = '\0';
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
@@ -560,7 +585,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;
}
@@ -582,52 +607,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) {
- DPRINTF("Write failed (%s)\n", strerror(errno));
- exit(1);
- }
- exit(0);
- /*NOTREACHED*/
-
- case -1:
+ pid = fork();
+ if (pid == -1) {
DPRINTF("Fork failed (%s)\n", strerror(errno));
exit(1);
- /*NOTREACHED*/
-
- default: /* parent */
- if (wait(&status) == -1) {
- DPRINTF("Wait failed (%s)\n", strerror(errno));
+ }
+ if (pid == 0) {
+ /* child */
+ if (swrite(fd, old, n) != CAST(ssize_t, n)) {
+ DPRINTF("Write failed (%s)\n", strerror(errno));
exit(1);
}
- DPRINTF("Grandchild wait return %#x\n", status);
+ exit(0);
}
- closefd(fdp[STDIN_FILENO], 1);
+ /* parent */
+ return pid;
}
static ssize_t
@@ -637,17 +652,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));
@@ -674,7 +689,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;
@@ -698,43 +715,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 */
+
+ /* 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) {
- fdp[STDIN_FILENO][0] = fd;
- (void) lseek(fd, (off_t)0, SEEK_SET);
+ (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]);
}
-
- for (i = 0; i < __arraycount(fdp); i++)
- copydesc(CAST(int, i), fdp[i]);
+///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);
- dprintf(STDERR_FILENO, "exec `%s' failed, %s",
+ 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",
- 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);
+ _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));
- goto err;
- }
- rv = OKDATA;
- if ((r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0)) > 0)
- break;
+ *newch = CAST(unsigned char *, malloc(bytes_max + 1));
+ if (*newch == NULL) {
+ rv = makeerror(newch, n, "No buffer, %s",
+ strerror(errno));
+ 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");
@@ -743,7 +785,7 @@ 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;
}
free(*newch);
if (r == 0)
@@ -753,7 +795,7 @@ 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';
@@ -761,7 +803,10 @@ err:
closefd(fdp[STDIN_FILENO], 1);
closefd(fdp[STDOUT_FILENO], 0);
closefd(fdp[STDERR_FILENO], 0);
- if (wait(&status) == -1) {
+
+ 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);
@@ -770,10 +815,19 @@ err:
} 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);
- closefd(fdp[STDIN_FILENO], 0);
- DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv);
-
return rv;
}
#endif
diff --git a/src/der.c b/src/der.c
index d017b63983f09..8867c568034dd 100644
--- a/src/der.c
+++ b/src/der.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.13 2018/06/23 15:15:26 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
#endif
#endif
@@ -56,7 +56,7 @@ FILE_RCSID("@(#)$File: der.c,v 1.13 2018/06/23 15:15:26 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
@@ -207,7 +207,7 @@ getlength(const uint8_t *c, size_t *p, size_t l)
static const char *
der_tag(char *buf, size_t len, uint32_t tag)
{
- if (tag < DER_TAG_LONG)
+ if (tag < DER_TAG_LONG)
strlcpy(buf, der__tag[tag], len);
else
snprintf(buf, len, "%#x", tag);
@@ -224,11 +224,11 @@ 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;
}
-
+
for (uint32_t i = 0; i < len; i++) {
uint32_t z = i << 1;
if (z < blen - 2)
@@ -245,18 +245,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)
@@ -304,22 +307,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);
@@ -343,7 +347,7 @@ printtag(uint32_t tag, const void *q, uint32_t len)
default:
break;
}
-
+
for (uint32_t i = 0; i < len; i++)
printf("%.2x", d[i]);
printf("\n");
@@ -367,8 +371,9 @@ printdata(size_t level, const void *v, size_t x, size_t l)
if (p + x >= ep)
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;
diff --git a/src/dprintf.c b/src/dprintf.c
index 3ae1581b16e86..027a64f39e29d 100644
--- a/src/dprintf.c
+++ b/src/dprintf.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -28,7 +28,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: dprintf.c,v 1.1 2015/11/13 15:36:14 christos Exp $")
+FILE_RCSID("@(#)$File: dprintf.c,v 1.2 2018/09/09 20:33:28 christos Exp $")
#endif /* lint */
#include <assert.h>
diff --git a/src/elfclass.h b/src/elfclass.h
index 5360b0b55a7e8..936d8dc912e07 100644
--- a/src/elfclass.h
+++ b/src/elfclass.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2008.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 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 AUTHOR 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
@@ -41,8 +41,8 @@
return toomany(ms, "program headers", phnum);
flags |= FLAGS_IS_CORE;
if (dophn_core(ms, clazz, swap, fd,
- (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ CAST(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,
- (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ CAST(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,
- (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
- (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+ CAST(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;
diff --git a/src/encoding.c b/src/encoding.c
index 3e7b9e584b08e..76244f87f95b0 100644
--- a/src/encoding.c
+++ b/src/encoding.c
@@ -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 *, calloc((size_t)1, mlen))) == NULL) {
+ if ((*ubuf = CAST(unichar *, calloc(CAST(size_t, 1), mlen))) == NULL) {
file_oomem(ms, mlen);
goto done;
}
mlen = (nbytes + 1) * sizeof(nbuf[0]);
- if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) {
+ if ((nbuf = CAST(unsigned char *,
+ calloc(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
diff --git a/src/file.c b/src/file.c
index 87dd1bb60f4c4..5b60b95f42401 100644
--- a/src/file.c
+++ b/src/file.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: file.c,v 1.175 2018/03/02 16:11:37 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.181 2019/03/28 20:54:03 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -128,6 +128,7 @@ private const struct {
{ "encoding", MAGIC_NO_CHECK_ENCODING },
{ "soft", MAGIC_NO_CHECK_SOFT },
{ "tar", MAGIC_NO_CHECK_TAR },
+ { "json", MAGIC_NO_CHECK_JSON },
{ "text", MAGIC_NO_CHECK_TEXT }, /* synonym for ascii */
{ "tokens", MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */
};
@@ -136,14 +137,15 @@ private struct {
const char *name;
int tag;
size_t value;
+ int set;
} pm[] = {
- { "indir", MAGIC_PARAM_INDIR_MAX, 0 },
- { "name", MAGIC_PARAM_NAME_MAX, 0 },
- { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
- { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
- { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 },
- { "regex", MAGIC_PARAM_REGEX_MAX, 0 },
- { "bytes", MAGIC_PARAM_BYTES_MAX, 0 },
+ { "indir", MAGIC_PARAM_INDIR_MAX, 0, 0 },
+ { "name", MAGIC_PARAM_NAME_MAX, 0, 0 },
+ { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0, 0 },
+ { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0, 0 },
+ { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0, 0 },
+ { "regex", MAGIC_PARAM_REGEX_MAX, 0, 0 },
+ { "bytes", MAGIC_PARAM_BYTES_MAX, 0, 0 },
};
private int posixly;
@@ -184,9 +186,7 @@ main(int argc, char *argv[])
char *progname;
/* makes islower etc work for other langs */
-#ifdef HAVE_SETLOCALE
(void)setlocale(LC_CTYPE, "");
-#endif
#ifdef __EMX__
/* sh-like wildcard expansion! Shouldn't hurt at least ... */
@@ -242,11 +242,11 @@ main(int argc, char *argv[])
flags |= MAGIC_ERROR;
break;
case 'e':
- for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++)
+ for (i = 0; i < __arraycount(nv); i++)
if (strcmp(nv[i].name, optarg) == 0)
break;
- if (i == sizeof(nv) / sizeof(nv[0]))
+ if (i == __arraycount(nv))
errflg++;
else
flags |= nv[i].value;
@@ -398,7 +398,8 @@ main(int argc, char *argv[])
}
else {
size_t j, wid, nw;
- for (wid = 0, j = (size_t)optind; j < (size_t)argc; j++) {
+ for (wid = 0, j = CAST(size_t, optind); j < CAST(size_t, argc);
+ j++) {
nw = file_mbswidth(argv[j]);
if (nw > wid)
wid = nw;
@@ -426,7 +427,7 @@ applyparam(magic_t magic)
size_t i;
for (i = 0; i < __arraycount(pm); i++) {
- if (pm[i].value == 0)
+ if (!pm[i].set)
continue;
if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1)
file_err(EXIT_FAILURE, "Can't set %s", pm[i].name);
@@ -446,6 +447,7 @@ setparam(const char *p)
if (strncmp(p, pm[i].name, s - p) != 0)
continue;
pm[i].value = atoi(s + 1);
+ pm[i].set = 1;
return;
}
badparm:
@@ -534,9 +536,8 @@ process(struct magic_set *ms, const char *inname, int wid)
(void)putc('\0', stdout);
if (nulsep < 2) {
(void)printf("%s", separator);
- (void)printf("%*s ",
- (int) (nopad ? 0 : (wid - file_mbswidth(inname))),
- "");
+ (void)printf("%*s ", CAST(int, nopad ? 0
+ : (wid - file_mbswidth(inname))), "");
}
}
@@ -563,8 +564,8 @@ file_mbswidth(const char *s)
while (n > 0) {
bytesconsumed = mbrtowc(&nextchar, s, n, &state);
- if (bytesconsumed == (size_t)(-1) ||
- bytesconsumed == (size_t)(-2)) {
+ if (bytesconsumed == CAST(size_t, -1) ||
+ bytesconsumed == CAST(size_t, -2)) {
/* Something went wrong, return something reasonable */
return old_n;
}
@@ -623,13 +624,13 @@ docprint(const char *opts, int def)
for (sp = p - 1; sp > opts && *sp == ' '; sp--)
continue;
- fprintf(stdout, "%.*s", (int)(p - opts), opts);
+ fprintf(stdout, "%.*s", CAST(int, p - opts), opts);
comma = 0;
for (i = 0; i < __arraycount(nv); i++) {
fprintf(stdout, "%s%s", comma++ ? ", " : "", nv[i].name);
- if (i && i % 5 == 0) {
- fprintf(stdout, ",\n%*s", (int)(p - sp - 1), "");
+ if (i && i % 5 == 0 && i != __arraycount(nv) - 1) {
+ fprintf(stdout, ",\n%*s", CAST(int, p - sp - 1), "");
comma = 0;
}
}
@@ -653,7 +654,7 @@ help(void)
#include "file_opts.h"
#undef OPT
#undef OPT_LONGONLY
- fprintf(stdout, "\nReport bugs to http://bugs.gw.com/\n");
+ fprintf(stdout, "\nReport bugs to https://bugs.astron.com/\n");
exit(EXIT_SUCCESS);
}
diff --git a/src/file.h b/src/file.h
index 57a84a80c0d5e..69a586ab73238 100644
--- a/src/file.h
+++ b/src/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.193 2018/05/24 18:09:17 christos Exp $
+ * @(#)$File: file.h,v 1.206 2019/05/07 02:27:11 christos Exp $
*/
#ifndef __file_h__
@@ -40,6 +40,9 @@
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
#ifdef WIN32
#ifdef _WIN64
@@ -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
@@ -450,12 +453,14 @@ struct stat;
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 *, int, const char *, const void *,
- size_t);
+protected int file_default(struct magic_set *, size_t);
+protected int file_buffer(struct magic_set *, int, struct stat *, const char *,
+ const void *, size_t);
protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
protected int file_vprintf(struct magic_set *, const char *, va_list)
__attribute__((__format__(__printf__, 2, 0)));
+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 *, ...)
@@ -473,6 +478,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);
@@ -501,19 +507,18 @@ 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 struct stat *,
+ const void *, size_t);
protected void buffer_fini(struct buffer *);
protected int buffer_fill(const struct buffer *);
-#if defined(HAVE_LOCALE_H)
#include <locale.h>
-#endif
#if defined(HAVE_XLOCALE_H)
#include <xlocale.h>
#endif
@@ -550,17 +555,6 @@ extern const char *file_names[];
extern const size_t file_nnames;
#endif
-#ifndef HAVE_STRERROR
-extern int sys_nerr;
-extern char *sys_errlist[];
-#define strerror(e) \
- (((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 HAVE_PREAD
ssize_t pread(int, void *, size_t, off_t);
#endif
@@ -600,17 +594,17 @@ struct tm *gmtime_r(const time_t *, struct tm *);
struct tm *localtime_r(const time_t *, struct tm *);
#endif
#ifndef HAVE_FMTCHECK
-const char *fmtcheck(const char *, const char *)
+const char *fmtcheck(const char *, const char *)
__attribute__((__format_arg__(2)));
#endif
#ifdef HAVE_LIBSECCOMP
-// basic filter
+// basic filter
// this mode should not interfere with normal operations
// only some dangerous syscalls are blacklisted
int enable_sandbox_basic(void);
-// enhanced filter
+// enhanced filter
// this mode allows only the necessary syscalls used during normal operation
// extensive testing required !!!
int enable_sandbox_full(void);
@@ -634,6 +628,9 @@ protected void file_warnx(const char *, ...)
#ifndef O_BINARY
#define O_BINARY 0
#endif
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 0
+#endif
#ifndef __cplusplus
#if defined(__GNUC__) && (__GNUC__ >= 3)
diff --git a/src/fmtcheck.c b/src/fmtcheck.c
index 486aa08681d37..fcad436b8eba7 100644
--- a/src/fmtcheck.c
+++ b/src/fmtcheck.c
@@ -235,7 +235,7 @@ fmtcheck(const char *f1, const char *f2)
EFT f1t, f2t;
if (!f1) return f2;
-
+
f1p = f1;
f1t = FMTCHECK_START;
f2p = f2;
diff --git a/src/fsmagic.c b/src/fsmagic.c
index c0a437a8f6d0e..25c4f811567f4 100644
--- a/src/fsmagic.c
+++ b/src/fsmagic.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -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
@@ -77,7 +80,7 @@ bad_link(struct magic_set *ms, int err, char *buf)
file_error(ms, err,
"broken symbolic link to %s", buf);
return -1;
- }
+ }
if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
return -1;
}
@@ -174,17 +177,17 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
return -1;
#endif
#ifdef S_ISGID
- if (sb->st_mode & S_ISGID)
+ if (sb->st_mode & S_ISGID)
if (file_printf(ms, "%ssetgid", COMMA) == -1)
return -1;
#endif
#ifdef S_ISVTX
- if (sb->st_mode & S_ISVTX)
+ if (sb->st_mode & S_ISVTX)
if (file_printf(ms, "%ssticky", COMMA) == -1)
return -1;
#endif
}
-
+
switch (sb->st_mode & S_IFMT) {
case S_IFDIR:
if (mime) {
@@ -196,7 +199,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
break;
#ifdef S_IFCHR
case S_IFCHR:
- /*
+ /*
* If -s has been specified, treat character special files
* like ordinary files. Otherwise, just report that they
* are block special files and go on to the next file.
@@ -231,7 +234,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
#endif
#ifdef S_IFBLK
case S_IFBLK:
- /*
+ /*
* If -s has been specified, treat block special files
* like ordinary files. Otherwise, just report that they
* are block special files and go on to the next file.
@@ -308,6 +311,15 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
buf[nch] = '\0'; /* readlink(2) does not do this */
/* If broken symlink, say so and quit early. */
+#ifdef __linux__
+ /*
+ * linux procfs/devfs makes symlinks like pipe:[3515864880]
+ * that we can't stat their readlink output, so stat the
+ * original filename instead.
+ */
+ if (stat(fn, &tstatbuf) < 0)
+ return bad_link(ms, errno, buf);
+#else
if (*buf == '/') {
if (stat(buf, &tstatbuf) < 0)
return bad_link(ms, errno, buf);
@@ -320,7 +332,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
} else {
if (tmp - fn + 1 > BUFSIZ) {
if (ms->flags & MAGIC_ERROR) {
- file_error(ms, 0,
+ file_error(ms, 0,
"path too long: `%s'", buf);
return -1;
}
@@ -345,6 +357,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (stat(tmp, &tstatbuf) < 0)
return bad_link(ms, errno, buf);
}
+#endif
/* Otherwise, handle it. */
if ((ms->flags & MAGIC_SYMLINK) != 0) {
diff --git a/src/funcs.c b/src/funcs.c
index 0bf92fe1c2509..23e7f32e63d26 100644
--- a/src/funcs.c
+++ b/src/funcs.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.104 2019/05/07 02:27:11 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -42,9 +42,7 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $")
#if defined(HAVE_WCTYPE_H)
#include <wctype.h>
#endif
-#if defined(HAVE_LIMITS_H)
#include <limits.h>
-#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)~0)
@@ -107,13 +105,13 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
if (lineno != 0) {
free(ms->o.buf);
ms->o.buf = NULL;
- file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
+ (void)file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
}
if (ms->o.buf && *ms->o.buf)
- file_printf(ms, " ");
- file_vprintf(ms, f, va);
+ (void)file_printf(ms, " ");
+ (void)file_vprintf(ms, f, va);
if (error > 0)
- file_printf(ms, " (%s)", strerror(error));
+ (void)file_printf(ms, " (%s)", strerror(error));
ms->event_flags |= EVENT_HAD_ERR;
ms->error = error;
}
@@ -162,36 +160,70 @@ file_badread(struct magic_set *ms)
#ifndef COMPILE_ONLY
+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, int fd, const char *inname __attribute__ ((__unused__)),
+file_buffer(struct magic_set *ms, int fd, struct stat *st,
+ const char *inname __attribute__ ((__unused__)),
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;
- buffer_init(&b, fd, buf, nb);
+ 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)";
@@ -240,6 +272,17 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
}
}
+ /* 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);
@@ -268,7 +311,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
rv = file_tryelf(ms, &b);
rbuf = file_pop_buffer(ms, pb);
- if (rv != 1) {
+ if (rv == -1) {
free(rbuf);
rbuf = NULL;
}
@@ -299,27 +342,18 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
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) {
@@ -364,9 +398,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 *
@@ -412,9 +446,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;
}
@@ -437,7 +471,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);
@@ -595,12 +629,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;
diff --git a/src/getopt_long.c b/src/getopt_long.c
index d357dc30f444a..43c4245619efa 100644
--- a/src/getopt_long.c
+++ b/src/getopt_long.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: getopt_long.c,v 1.6 2009/02/13 18:48:05 christos Exp $")
+FILE_RCSID("@(#)$File: getopt_long.c,v 1.7 2018/09/09 20:33:28 christos Exp $")
#endif /* lint */
#include <assert.h>
@@ -124,7 +124,7 @@ gcd(a, b)
b = c;
c = a % b;
}
-
+
return b;
}
@@ -223,7 +223,7 @@ start:
place = EMSG;
if (IN_ORDER) {
/*
- * GNU extension:
+ * GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
@@ -269,7 +269,7 @@ start:
}
if (optchar == 'W' && oli[1] == ';') { /* -W long-option */
/* XXX: what if no long options provided (called by getopt)? */
- if (*place)
+ if (*place)
return -2;
if (++optind >= nargc) { /* no arg */
@@ -404,7 +404,7 @@ getopt_long(nargc, nargv, options, long_options, idx)
has_equal++;
} else
current_argv_len = strlen(current_argv);
-
+
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
@@ -488,7 +488,7 @@ getopt_long(nargc, nargv, options, long_options, idx)
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
retval = 0;
- } else
+ } else
retval = long_options[match].val;
if (idx)
*idx = match;
diff --git a/src/is_json.c b/src/is_json.c
new file mode 100644
index 0000000000000..206ec3795e54e
--- /dev/null
+++ b/src/is_json.c
@@ -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
diff --git a/src/is_tar.c b/src/is_tar.c
index 7110604f9e81b..82b08051fbdda 100644
--- a/src/is_tar.c
+++ b/src/is_tar.c
@@ -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;
diff --git a/src/magic.c b/src/magic.c
index 1448a69bcad52..da5baf108e5d9 100644
--- a/src/magic.c
+++ b/src/magic.c
@@ -33,7 +33,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"
@@ -44,9 +44,7 @@ FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $")
#ifdef QUICK
#include <sys/mman.h>
#endif
-#ifdef HAVE_LIMITS_H
#include <limits.h> /* for PIPE_BUF */
-#endif
#if defined(HAVE_UTIMES)
# include <sys/time.h>
@@ -314,7 +312,8 @@ magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
{
if (ms == NULL)
return -1;
- return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs);
+ return buffer_apprentice(ms, RCAST(struct magic **, bufs),
+ sizes, nbufs);
}
#endif
@@ -407,7 +406,8 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
struct stat sb;
ssize_t nbytes = 0; /* number of bytes read from a datafile */
int ispipe = 0;
- off_t pos = (off_t)-1;
+ int okstat = 0;
+ off_t pos = CAST(off_t, -1);
if (file_reset(ms, 1) == -1)
goto out;
@@ -435,25 +435,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
if (fd == STDIN_FILENO)
_setmode(STDIN_FILENO, O_BINARY);
#endif
-
- if (inname == NULL) {
- if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
- ispipe = 1;
- else
- pos = lseek(fd, (off_t)0, SEEK_CUR);
- } else {
- int flags = O_RDONLY|O_BINARY;
- int okstat = stat(inname, &sb) == 0;
-
- if (okstat && S_ISFIFO(sb.st_mode)) {
-#ifdef O_NONBLOCK
- flags |= O_NONBLOCK;
-#endif
- ispipe = 1;
- }
-
+ if (inname != NULL) {
+ int flags = O_RDONLY|O_BINARY|O_NONBLOCK;
errno = 0;
if ((fd = open(inname, flags)) < 0) {
+ okstat = stat(inname, &sb) == 0;
+ if (okstat && S_ISFIFO(sb.st_mode))
+ ispipe = 1;
#ifdef WIN32
/*
* Can't stat, can't open. It may have been opened in
@@ -472,24 +460,29 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
rv = 0;
goto done;
}
-#ifdef O_NONBLOCK
- if ((flags = fcntl(fd, F_GETFL)) != -1) {
- flags &= ~O_NONBLOCK;
- (void)fcntl(fd, F_SETFL, flags);
- }
-#endif
+ }
+
+ if (fd != -1) {
+ if (!okstat)
+ okstat = fstat(fd, &sb) == 0;
+ if (okstat && S_ISFIFO(sb.st_mode))
+ ispipe = 1;
+ if (inname == NULL)
+ pos = lseek(fd, CAST(off_t, 0), SEEK_CUR);
}
/*
* try looking at the first ms->bytes_max bytes
*/
if (ispipe) {
- ssize_t r = 0;
+ if (fd != -1) {
+ ssize_t r = 0;
- while ((r = sread(fd, (void *)&buf[nbytes],
- (size_t)(ms->bytes_max - nbytes), 1)) > 0) {
- nbytes += r;
- if (r < PIPE_BUF) break;
+ while ((r = sread(fd, RCAST(void *, &buf[nbytes]),
+ CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) {
+ nbytes += r;
+ if (r < PIPE_BUF) break;
+ }
}
if (nbytes == 0 && inname) {
@@ -500,14 +493,14 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
goto done;
}
- } else {
+ } else if (fd != -1) {
/* Windows refuses to read from a big console buffer. */
size_t howmany =
#if defined(WIN32)
- _isatty(fd) ? 8 * 1024 :
+ _isatty(fd) ? 8 * 1024 :
#endif
- ms->bytes_max;
- if ((nbytes = read(fd, (char *)buf, howmany)) == -1) {
+ ms->bytes_max;
+ if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) {
if (inname == NULL && fd != STDIN_FILENO)
file_error(ms, errno, "cannot read fd %d", fd);
else
@@ -518,13 +511,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
}
(void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
- if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
+ if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, CAST(size_t, nbytes)) == -1)
goto done;
rv = 0;
done:
free(buf);
if (fd != -1) {
- if (pos != (off_t)-1)
+ if (pos != CAST(off_t, -1))
(void)lseek(fd, pos, SEEK_SET);
close_and_restore(ms, inname, fd, &sb);
}
@@ -544,7 +537,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, -1, NULL, buf, nb) == -1) {
+ if (file_buffer(ms, -1, NULL, NULL, buf, nb) == -1) {
return NULL;
}
return file_getbuffer(ms);
@@ -598,27 +591,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;
@@ -629,27 +624,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;
diff --git a/src/magic.h.in b/src/magic.h.in
index 1134bdc886d41..0580fa21cceac 100644
--- a/src/magic.h.in
+++ b/src/magic.h.in
@@ -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\
diff --git a/src/mygetopt.h b/src/mygetopt.h
index ef87525eaf5bb..d766762631d13 100644
--- a/src/mygetopt.h
+++ b/src/mygetopt.h
@@ -64,5 +64,5 @@ struct option {
int getopt_long(int, char * const *, const char *,
const struct option *, int *);
-
+
#endif /* !_GETOPT_H_ */
diff --git a/src/print.c b/src/print.c
index 0b918636bc5e5..391a7fbe15621 100644
--- a/src/print.c
+++ b/src/print.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -32,7 +32,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>
@@ -43,8 +43,6 @@ FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $")
#endif
#include <time.h>
-#define SZOF(a) (sizeof(a) / sizeof(a[0]))
-
#include "cdf.h"
#ifndef COMPILE_ONLY
@@ -65,9 +63,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 */
@@ -78,16 +76,16 @@ file_mdump(struct magic *m)
if (IS_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);
@@ -112,14 +110,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);
@@ -141,7 +140,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:
@@ -149,7 +148,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:
@@ -217,11 +217,11 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
va_list va;
/* cuz we use stdout for most, stderr here */
- (void) fflush(stdout);
+ (void) fflush(stdout);
if (ms->file)
(void) fprintf(stderr, "%s, %lu: ", ms->file,
- (unsigned long)ms->line);
+ CAST(unsigned long, ms->line));
(void) fprintf(stderr, "Warning: ");
va_start(va, f);
(void) vfprintf(stderr, f, va);
@@ -243,7 +243,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) {
diff --git a/src/readcdf.c b/src/readcdf.c
index 4b86e6fed08d6..e6ea8e47fb6b4 100644
--- a/src/readcdf.c
+++ b/src/readcdf.c
@@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.67 2018/04/15 19:57:07 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.73 2019/03/12 20:43:05 christos Exp $")
#endif
#include <assert.h>
@@ -39,10 +39,6 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.67 2018/04/15 19:57:07 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 {
@@ -204,7 +200,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
&& len--; s += k) {
if (*s == '\0')
break;
- if (isprint((unsigned char)*s))
+ if (isprint(CAST(unsigned char, *s)))
vbuf[j++] = *s;
}
if (j == sizeof(vbuf))
@@ -252,7 +248,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
return -1;
}
}
- if (!NOTMIME(ms)) {
+ if (ms->flags & MAGIC_MIME_TYPE) {
if (str == NULL)
return 0;
if (file_printf(ms, "application/%s", str) == -1)
@@ -285,7 +281,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
return -1;
}
free(cat);
- } else {
+ } else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/CDFV2") == -1)
return -1;
}
@@ -318,19 +314,19 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
case 2:
if (file_printf(ms, ", Os: Windows, Version %d.%d",
si.si_os_version & 0xff,
- (uint32_t)si.si_os_version >> 8) == -1)
+ CAST(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,
+ 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,
- (uint32_t)si.si_os_version >> 8) == -1)
+ CAST(uint32_t, si.si_os_version) >> 8) == -1)
return -2;
break;
}
@@ -353,11 +349,11 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
#ifdef notdef
private char *
format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
- snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
+ snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
PRIx64 "-%.12" PRIx64,
(uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL,
(uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL,
- (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
+ (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
(uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL,
(uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL);
return buf;
@@ -406,7 +402,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);
}
@@ -416,7 +412,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)
@@ -436,7 +432,7 @@ private struct sinfo {
const char *sections[5];
const int types[5];
} sectioninfo[] = {
- { "Encrypted", "encrypted",
+ { "Encrypted", "encrypted",
{
"EncryptedPackage", "EncryptedSummary",
NULL, NULL, NULL,
@@ -448,7 +444,7 @@ private struct sinfo {
},
},
- { "QuickBooks", "quickbooks",
+ { "QuickBooks", "quickbooks",
{
#if 0
"TaxForms", "PDFTaxForms", "modulesInBackup",
@@ -527,7 +523,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;
}
@@ -540,7 +536,7 @@ 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;
@@ -614,7 +610,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;
}
@@ -661,19 +657,20 @@ out2:
out1:
free(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;
}
diff --git a/src/readelf.c b/src/readelf.c
index db0b35a506a71..ef61d4cd600fe 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2003.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 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 AUTHOR 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
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.144 2018/07/08 23:37:33 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.165 2019/05/07 02:27:11 christos Exp $")
#endif
#ifdef BUILTIN_ELF
@@ -69,7 +69,7 @@ toomany(struct magic_set *ms, const char *name, uint16_t num)
{
if (file_printf(ms, ", too many %s (%u)", name, num) == -1)
return -1;
- return 0;
+ return 1;
}
private uint16_t
@@ -85,7 +85,7 @@ getu16(int swap, uint16_t value)
retval.c[0] = tmpval.c[1];
retval.c[1] = tmpval.c[0];
-
+
return retval.ui;
} else
return value;
@@ -106,7 +106,7 @@ getu32(int swap, uint32_t value)
retval.c[1] = tmpval.c[2];
retval.c[2] = tmpval.c[1];
retval.c[3] = tmpval.c[0];
-
+
return retval.ui;
} else
return value;
@@ -131,7 +131,7 @@ getu64(int swap, uint64_t value)
retval.c[5] = tmpval.c[2];
retval.c[6] = tmpval.c[1];
retval.c[7] = tmpval.c[0];
-
+
return retval.ui;
} else
return value;
@@ -262,7 +262,10 @@ static const size_t prpsoffsets32[] = {
84, /* SunOS 5.x (short name) */
44, /* Linux (command line) */
- 28, /* Linux 2.0.36 (short name) */
+ 28, /* Linux (short name) */
+
+ 48, /* Linux PowerPC (command line) */
+ 32, /* Linux PowerPC (short name) */
8, /* FreeBSD */
};
@@ -282,8 +285,8 @@ static const size_t prpsoffsets64[] = {
16, /* FreeBSD, 64-bit */
};
-#define NOFFSETS32 (sizeof(prpsoffsets32) / sizeof(prpsoffsets32[0]))
-#define NOFFSETS64 (sizeof(prpsoffsets64) / sizeof(prpsoffsets64[0]))
+#define NOFFSETS32 __arraycount(prpsoffsets32)
+#define NOFFSETS64 __arraycount(prpsoffsets64)
#define NOFFSETS (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
@@ -352,6 +355,11 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
off_t ph_off = off;
int ph_num = num;
+ if (num == 0) {
+ if (file_printf(ms, ", no program header") == -1)
+ return -1;
+ return 0;
+ }
if (size != xph_sizeof) {
if (file_printf(ms, ", corrupted program header size") == -1)
return -1;
@@ -388,9 +396,9 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
}
offset = 0;
for (;;) {
- if (offset >= (size_t)bufsize)
+ if (offset >= CAST(size_t, bufsize))
break;
- offset = donote(ms, nbuf, offset, (size_t)bufsize,
+ offset = donote(ms, nbuf, offset, CAST(size_t, bufsize),
clazz, swap, 4, flags, notecount, fd, ph_off,
ph_num, fsize);
if (offset == 0)
@@ -402,7 +410,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
}
#endif
-static void
+static int
do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
{
uint32_t desc;
@@ -410,7 +418,7 @@ do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
desc = elf_getu32(swap, desc);
if (file_printf(ms, ", for NetBSD") == -1)
- return;
+ return -1;
/*
* The version number used to be stuck as 199905, and was thus
* basically content-free. Newer versions of NetBSD have fixed
@@ -430,24 +438,25 @@ do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
uint32_t ver_maj = desc / 100000000;
if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
- return;
+ return -1;
if (ver_rel == 0 && ver_patch != 0) {
if (file_printf(ms, ".%u", ver_patch) == -1)
- return;
+ return -1;
} else if (ver_rel != 0) {
while (ver_rel > 26) {
if (file_printf(ms, "Z") == -1)
- return;
+ return -1;
ver_rel -= 26;
}
if (file_printf(ms, "%c", 'A' + ver_rel - 1)
== -1)
- return;
+ return -1;
}
}
+ return 0;
}
-static void
+static int
do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
{
uint32_t desc;
@@ -455,71 +464,72 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
memcpy(&desc, v, sizeof(desc));
desc = elf_getu32(swap, desc);
if (file_printf(ms, ", for FreeBSD") == -1)
- return;
+ return -1;
/*
* Contents is __FreeBSD_version, whose relation to OS
* versions is defined by a huge table in the Porter's
* Handbook. This is the general scheme:
- *
+ *
* Releases:
* Mmp000 (before 4.10)
* Mmi0p0 (before 5.0)
* Mmm0p0
- *
+ *
* Development branches:
* Mmpxxx (before 4.6)
* Mmp1xx (before 4.10)
* Mmi1xx (before 5.0)
* M000xx (pre-M.0)
* Mmm1xx
- *
+ *
* M = major version
* m = minor version
* i = minor version increment (491000 -> 4.10)
* p = patchlevel
* x = revision
- *
+ *
* The first release of FreeBSD to use ELF by default
* was version 3.0.
*/
if (desc == 460002) {
if (file_printf(ms, " 4.6.2") == -1)
- return;
+ return -1;
} else if (desc < 460100) {
if (file_printf(ms, " %d.%d", desc / 100000,
desc / 10000 % 10) == -1)
- return;
+ return -1;
if (desc / 1000 % 10 > 0)
if (file_printf(ms, ".%d", desc / 1000 % 10) == -1)
- return;
+ return -1;
if ((desc % 1000 > 0) || (desc % 100000 == 0))
if (file_printf(ms, " (%d)", desc) == -1)
- return;
+ return -1;
} else if (desc < 500000) {
if (file_printf(ms, " %d.%d", desc / 100000,
desc / 10000 % 10 + desc / 1000 % 10) == -1)
- return;
+ return -1;
if (desc / 100 % 10 > 0) {
if (file_printf(ms, " (%d)", desc) == -1)
- return;
+ return -1;
} else if (desc / 10 % 10 > 0) {
if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
- return;
+ return -1;
}
} else {
if (file_printf(ms, " %d.%d", desc / 100000,
desc / 1000 % 100) == -1)
- return;
+ return -1;
if ((desc / 100 % 10 > 0) ||
(desc % 100000 / 100 == 0)) {
if (file_printf(ms, " (%d)", desc) == -1)
- return;
+ return -1;
} else if (desc / 10 % 10 > 0) {
if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
- return;
+ return -1;
}
}
+ return 0;
}
private int
@@ -528,7 +538,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
size_t noff, size_t doff, int *flags)
{
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+ if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "GNU") == 0 &&
type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) {
uint8_t desc[20];
const char *btype;
@@ -549,18 +559,18 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
break;
}
if (file_printf(ms, ", BuildID[%s]=", btype) == -1)
- return 1;
+ return -1;
memcpy(desc, &nbuf[doff], descsz);
for (i = 0; i < descsz; i++)
if (file_printf(ms, "%02x", desc[i]) == -1)
- return 1;
+ return -1;
return 1;
}
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "Go") == 0 &&
+ if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "Go") == 0 &&
type == NT_GO_BUILD_ID && descsz < 128) {
- if (file_printf(ms, ", Go BuildID=%s",
- (char *)&nbuf[doff]) == -1)
- return 1;
+ if (file_printf(ms, ", Go BuildID=%.*s",
+ CAST(int, descsz), RCAST(char *, &nbuf[doff])) == -1)
+ return -1;
return 1;
}
return 0;
@@ -571,88 +581,95 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int swap, uint32_t namesz, uint32_t descsz,
size_t noff, size_t doff, int *flags)
{
- if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
- type == NT_GNU_VERSION && descsz == 2) {
- *flags |= FLAGS_DID_OS_NOTE;
- file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
+ const char *name = RCAST(const char *, &nbuf[noff]);
+
+ if (namesz == 5 && strcmp(name, "SuSE") == 0 &&
+ type == NT_GNU_VERSION && descsz == 2) {
+ *flags |= FLAGS_DID_OS_NOTE;
+ if (file_printf(ms, ", for SuSE %d.%d", nbuf[doff],
+ nbuf[doff + 1]) == -1)
+ return -1;
return 1;
}
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+ if (namesz == 4 && strcmp(name, "GNU") == 0 &&
type == NT_GNU_VERSION && descsz == 16) {
uint32_t desc[4];
memcpy(desc, &nbuf[doff], sizeof(desc));
*flags |= FLAGS_DID_OS_NOTE;
if (file_printf(ms, ", for GNU/") == -1)
- return 1;
+ return -1;
switch (elf_getu32(swap, desc[0])) {
case GNU_OS_LINUX:
if (file_printf(ms, "Linux") == -1)
- return 1;
+ return -1;
break;
case GNU_OS_HURD:
if (file_printf(ms, "Hurd") == -1)
- return 1;
+ return -1;
break;
case GNU_OS_SOLARIS:
if (file_printf(ms, "Solaris") == -1)
- return 1;
+ return -1;
break;
case GNU_OS_KFREEBSD:
if (file_printf(ms, "kFreeBSD") == -1)
- return 1;
+ return -1;
break;
case GNU_OS_KNETBSD:
if (file_printf(ms, "kNetBSD") == -1)
- return 1;
+ return -1;
break;
default:
if (file_printf(ms, "<unknown>") == -1)
- return 1;
+ return -1;
}
if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
- return 1;
+ return -1;
return 1;
}
- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+ if (namesz == 7 && strcmp(name, "NetBSD") == 0) {
if (type == NT_NETBSD_VERSION && descsz == 4) {
*flags |= FLAGS_DID_OS_NOTE;
- do_note_netbsd_version(ms, swap, &nbuf[doff]);
+ if (do_note_netbsd_version(ms, swap, &nbuf[doff]) == -1)
+ return -1;
return 1;
}
}
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
+ if (namesz == 8 && strcmp(name, "FreeBSD") == 0) {
if (type == NT_FREEBSD_VERSION && descsz == 4) {
*flags |= FLAGS_DID_OS_NOTE;
- do_note_freebsd_version(ms, swap, &nbuf[doff]);
+ if (do_note_freebsd_version(ms, swap, &nbuf[doff])
+ == -1)
+ return -1;
return 1;
}
}
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
+ if (namesz == 8 && strcmp(name, "OpenBSD") == 0 &&
type == NT_OPENBSD_VERSION && descsz == 4) {
*flags |= FLAGS_DID_OS_NOTE;
if (file_printf(ms, ", for OpenBSD") == -1)
- return 1;
+ return -1;
/* Content of note is always 0 */
return 1;
}
- if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
+ if (namesz == 10 && strcmp(name, "DragonFly") == 0 &&
type == NT_DRAGONFLY_VERSION && descsz == 4) {
uint32_t desc;
*flags |= FLAGS_DID_OS_NOTE;
if (file_printf(ms, ", for DragonFly") == -1)
- return 1;
+ return -1;
memcpy(&desc, &nbuf[doff], sizeof(desc));
desc = elf_getu32(swap, desc);
if (file_printf(ms, " %d.%d.%d", desc / 100000,
desc / 10000 % 10, desc % 10000) == -1)
- return 1;
+ return -1;
return 1;
}
return 0;
@@ -663,7 +680,9 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int swap, uint32_t namesz, uint32_t descsz,
size_t noff, size_t doff, int *flags)
{
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
+ const char *name = RCAST(const char *, &nbuf[noff]);
+
+ if (namesz == 4 && strcmp(name, "PaX") == 0 &&
type == NT_NETBSD_PAX && descsz == 4) {
static const char *pax[] = {
"+mprotect",
@@ -682,14 +701,14 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
desc = elf_getu32(swap, desc);
if (desc && file_printf(ms, ", PaX: ") == -1)
- return 1;
+ return -1;
for (i = 0; i < __arraycount(pax); i++) {
- if (((1 << (int)i) & desc) == 0)
+ if (((1 << CAST(int, i)) & desc) == 0)
continue;
if (file_printf(ms, "%s%s", did++ ? "," : "",
pax[i]) == -1)
- return 1;
+ return -1;
}
return 1;
}
@@ -702,6 +721,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
size_t noff, size_t doff, int *flags, size_t size, int clazz)
{
#ifdef ELFCORE
+ const char *name = RCAST(const char *, &nbuf[noff]);
+
int os_style = -1;
/*
* Sigh. The 2.0.36 kernel in Debian 2.1, at
@@ -717,16 +738,16 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
* doesn't include the terminating null in the
* name....
*/
- if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
- (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
+ if ((namesz == 4 && strncmp(name, "CORE", 4) == 0) ||
+ (namesz == 5 && strcmp(name, "CORE") == 0)) {
os_style = OS_STYLE_SVR4;
- }
+ }
- if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
+ if ((namesz == 8 && strcmp(name, "FreeBSD") == 0)) {
os_style = OS_STYLE_FREEBSD;
}
- if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
+ if ((namesz >= 11 && strncmp(name, "NetBSD-CORE", 11)
== 0)) {
os_style = OS_STYLE_NETBSD;
}
@@ -734,7 +755,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
if (file_printf(ms, ", %s-style", os_style_names[os_style])
== -1)
- return 1;
+ return -1;
*flags |= FLAGS_DID_CORE_STYLE;
*flags |= os_style;
}
@@ -745,26 +766,48 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
char sbuf[512];
struct NetBSD_elfcore_procinfo pi;
memset(&pi, 0, sizeof(pi));
- memcpy(&pi, nbuf + doff, descsz);
+ memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi)));
if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
"gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
file_printable(sbuf, sizeof(sbuf),
- CAST(char *, pi.cpi_name)),
- elf_getu32(swap, (uint32_t)pi.cpi_pid),
+ RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)),
+ elf_getu32(swap, CAST(uint32_t, pi.cpi_pid)),
elf_getu32(swap, pi.cpi_euid),
elf_getu32(swap, pi.cpi_egid),
elf_getu32(swap, pi.cpi_nlwps),
- elf_getu32(swap, (uint32_t)pi.cpi_siglwp),
+ elf_getu32(swap, CAST(uint32_t, pi.cpi_siglwp)),
elf_getu32(swap, pi.cpi_signo),
elf_getu32(swap, pi.cpi_sigcode)) == -1)
- return 1;
+ return -1;
*flags |= FLAGS_DID_CORE;
return 1;
}
break;
+ case OS_STYLE_FREEBSD:
+ if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
+ size_t argoff, pidoff;
+
+ if (clazz == ELFCLASS32)
+ argoff = 4 + 4 + 17;
+ else
+ argoff = 4 + 4 + 8 + 17;
+ if (file_printf(ms, ", from '%.80s'", nbuf + doff +
+ argoff) == -1)
+ return -1;
+ pidoff = argoff + 81 + 2;
+ if (doff + pidoff + 4 <= size) {
+ if (file_printf(ms, ", pid=%u",
+ elf_getu32(swap, *RCAST(uint32_t *, (nbuf +
+ doff + pidoff)))) == -1)
+ return -1;
+ }
+ *flags |= FLAGS_DID_CORE;
+ }
+ break;
+
default:
if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
size_t i, j;
@@ -847,8 +890,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
i = k;
}
- cname = (unsigned char *)
- &nbuf[doff + prpsoffsets(i)];
+ cname = CAST(unsigned char *,
+ &nbuf[doff + prpsoffsets(i)]);
for (cp = cname; cp < nbuf + size && *cp
&& isprint(*cp); cp++)
continue;
@@ -859,8 +902,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
while (cp > cname && isspace(cp[-1]))
cp--;
if (file_printf(ms, ", from '%.*s'",
- (int)(cp - cname), cname) == -1)
- return 1;
+ CAST(int, cp - cname), cname) == -1)
+ return -1;
*flags |= FLAGS_DID_CORE;
return 1;
@@ -886,7 +929,8 @@ get_offset_from_virtaddr(struct magic_set *ms, int swap, int clazz, int fd,
* virtual address in which the "virtaddr" belongs to.
*/
for ( ; num; num--) {
- if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
+ if (pread(fd, xph_addr, xph_sizeof, off) <
+ CAST(ssize_t, xph_sizeof)) {
file_badread(ms);
return -1;
}
@@ -916,7 +960,8 @@ get_string_on_virtaddr(struct magic_set *ms,
offset = get_offset_from_virtaddr(ms, swap, clazz, fd, ph_off, ph_num,
fsize, virtaddr);
- if ((buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) {
+ if (offset < 0 ||
+ (buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) {
file_badread(ms);
return 0;
}
@@ -925,7 +970,7 @@ get_string_on_virtaddr(struct magic_set *ms,
/* We expect only printable characters, so return if buffer contains
* non-printable character before the '\0' or just '\0'. */
- for (bptr = buf; *bptr && isprint((unsigned char)*bptr); bptr++)
+ for (bptr = buf; *bptr && isprint(CAST(unsigned char, *bptr)); bptr++)
continue;
if (*bptr != '\0')
return 0;
@@ -1027,13 +1072,13 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
if (buflen == 0)
continue;
-
+
if (file_printf(ms, ", %s: '%s'", tag, buf) == -1)
- return 0;
+ return -1;
} else {
- if (file_printf(ms, ", %s: %d", tag, (int) xauxv_val)
- == -1)
- return 0;
+ if (file_printf(ms, ", %s: %d", tag,
+ CAST(int, xauxv_val)) == -1)
+ return -1;
}
}
return 1;
@@ -1062,7 +1107,7 @@ dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
switch (xdh_tag) {
case DT_FLAGS_1:
- if (xdh_val == DF_1_PIE)
+ if (xdh_val & DF_1_PIE)
ms->mode |= 0111;
else
ms->mode &= ~0111;
@@ -1110,14 +1155,16 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
}
if (namesz & 0x80000000) {
- file_printf(ms, ", bad note name size %#lx",
- CAST(unsigned long, namesz));
+ if (file_printf(ms, ", bad note name size %#lx",
+ CAST(unsigned long, namesz)) == -1)
+ return -1;
return 0;
}
if (descsz & 0x80000000) {
- file_printf(ms, ", bad note description size %#lx",
- CAST(unsigned long, descsz));
+ if (file_printf(ms, ", bad note description size %#lx",
+ CAST(unsigned long, descsz)) == -1)
+ return -1;
return 0;
}
@@ -1151,7 +1198,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
namesz, descsz, noff, doff, flags))
return offset;
}
-
+
if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
if (do_pax_note(ms, nbuf, xnh_type, swap,
namesz, descsz, noff, doff, flags))
@@ -1171,7 +1218,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
return offset;
}
- if (namesz == 7 && strcmp(CAST(char *, &nbuf[noff]), "NetBSD") == 0) {
+ if (namesz == 7 && strcmp(RCAST(char *, &nbuf[noff]), "NetBSD") == 0) {
int descw, flag;
const char *str, *tag;
if (descsz > 100)
@@ -1202,7 +1249,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
if (*flags & flag)
return offset;
- str = CAST(const char *, &nbuf[doff]);
+ str = RCAST(const char *, &nbuf[doff]);
descw = CAST(int, descsz);
*flags |= flag;
file_printf(ms, ", %s: %.*s", tag, descw, str);
@@ -1278,6 +1325,11 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
char name[50];
ssize_t namesize;
+ if (num == 0) {
+ if (file_printf(ms, ", no section header") == -1)
+ return -1;
+ return 0;
+ }
if (size != xsh_sizeof) {
if (file_printf(ms, ", corrupted section header size") == -1)
return -1;
@@ -1343,7 +1395,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
CAST(uintmax_t, xsh_size),
CAST(uintmax_t, fsize)) == -1)
return -1;
- return 0;
+ return 0;
}
if ((nbuf = malloc(xsh_size)) == NULL) {
file_error(ms, errno, "Cannot allocate memory"
@@ -1428,7 +1480,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
return -1;
break;
}
- // gnu attributes
+ // gnu attributes
#endif
break;
}
@@ -1548,7 +1600,12 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
char interp[BUFSIZ];
ssize_t bufsize;
size_t offset, align, len;
-
+
+ if (num == 0) {
+ if (file_printf(ms, ", no program header") == -1)
+ return -1;
+ return 0;
+ }
if (size != xph_sizeof) {
if (file_printf(ms, ", corrupted program header size") == -1)
return -1;
@@ -1558,7 +1615,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
interp[0] = '\0';
for ( ; num; num--) {
int doread;
- if (pread(fd, xph_addr, xph_sizeof, off) <
+ if (pread(fd, xph_addr, xph_sizeof, off) <
CAST(ssize_t, xph_sizeof)) {
file_badread(ms);
return -1;
@@ -1579,7 +1636,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
continue;
if (((align = xph_align) & 0x80000000UL) != 0 ||
align < 4) {
- if (file_printf(ms,
+ if (file_printf(ms,
", invalid note alignment %#lx",
CAST(unsigned long, align)) == -1)
return -1;
@@ -1613,8 +1670,10 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
switch (xph_type) {
case PT_DYNAMIC:
offset = 0;
+ // Let DF_1 determine if we are PIE or not.
+ ms->mode &= ~0111;
for (;;) {
- if (offset >= (size_t)bufsize)
+ if (offset >= CAST(size_t, bufsize))
break;
offset = dodynamic(ms, nbuf, offset,
CAST(size_t, bufsize), clazz, swap);
@@ -1626,7 +1685,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
case PT_INTERP:
if (bufsize && nbuf[0]) {
nbuf[bufsize - 1] = '\0';
- memcpy(interp, nbuf, bufsize);
+ memcpy(interp, nbuf, CAST(size_t, bufsize));
} else
strlcpy(interp, "*empty*", sizeof(interp));
break;
@@ -1637,7 +1696,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
*/
offset = 0;
for (;;) {
- if (offset >= (size_t)bufsize)
+ if (offset >= CAST(size_t, bufsize))
break;
offset = donote(ms, nbuf, offset,
CAST(size_t, bufsize), clazz, swap, align,
@@ -1655,7 +1714,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
return -1;
if (interp[0])
if (file_printf(ms, ", interpreter %s",
- file_printable(ibuf, sizeof(ibuf), interp)) == -1)
+ file_printable(ibuf, sizeof(ibuf), interp, sizeof(interp)))
+ == -1)
return -1;
return 0;
}
@@ -1665,7 +1725,7 @@ protected int
file_tryelf(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;
union {
int32_t l;
@@ -1674,6 +1734,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
int clazz;
int swap;
struct stat st;
+ const struct stat *stp;
off_t fsize;
int flags = 0;
Elf32_Ehdr elf32hdr;
@@ -1687,7 +1748,8 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
* file locations and thus file(1) cannot determine it from easily.
* Instead we traverse thru all section headers until a symbol table
* one is found or else the binary is stripped.
- * Return immediately if it's not ELF (so we avoid pipe2file unless needed).
+ * Return immediately if it's not ELF (so we avoid pipe2file unless
+ * needed).
*/
if (buf[EI_MAG0] != ELFMAG0
|| (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
@@ -1701,12 +1763,25 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
&& (errno == ESPIPE))
fd = file_pipe2file(ms, fd, buf, nbytes);
- if (fstat(fd, &st) == -1) {
- file_badread(ms);
+ if (fd == -1) {
+ file_badread(ms);
return -1;
}
- if (S_ISREG(st.st_mode) || st.st_size != 0)
- fsize = st.st_size;
+
+ stp = &b->st;
+ /*
+ * b->st.st_size != 0 if previous fstat() succeeded,
+ * which is likely, we can avoid extra stat() call.
+ */
+ if (b->st.st_size == 0) {
+ stp = &st;
+ if (fstat(fd, &st) == -1) {
+ file_badread(ms);
+ return -1;
+ }
+ }
+ if (S_ISREG(stp->st_mode) || stp->st_size != 0)
+ fsize = stp->st_size;
else
fsize = SIZE_UNKNOWN;
diff --git a/src/readelf.h b/src/readelf.h
index 6ae63f2d950da..809d3f7573bd1 100644
--- a/src/readelf.h
+++ b/src/readelf.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2003.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 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 AUTHOR 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
@@ -304,7 +304,7 @@ typedef struct {
#define GNU_OS_KNETBSD 4
/*
- * GNU Hardware capability information
+ * GNU Hardware capability information
* word[0]: Number of entries
* word[1]: Bitmask of enabled entries
* Followed by a byte id, and a NUL terminated string per entry
@@ -313,7 +313,7 @@ typedef struct {
/*
* GNU Build ID generated by ld
- * 160 bit SHA1 [default]
+ * 160 bit SHA1 [default]
* 128 bit md5 or uuid
*/
#define NT_GNU_BUILD_ID 3
diff --git a/src/seccomp.c b/src/seccomp.c
index a5abb4a159f98..1b9d9b8559377 100644
--- a/src/seccomp.c
+++ b/src/seccomp.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: seccomp.c,v 1.6 2018/06/26 20:29:29 christos Exp $")
+FILE_RCSID("@(#)$File: seccomp.c,v 1.8 2019/02/24 18:12:04 christos Exp $")
#endif /* lint */
#if HAVE_LIBSECCOMP
@@ -126,14 +126,14 @@ enable_sandbox_basic(void)
DENY_RULE (socket);
// ...
-
+
// applying filter...
if (seccomp_load (ctx) == -1)
goto out;
// free ctx after the filter has been loaded into the kernel
seccomp_release(ctx);
return 0;
-
+
out:
seccomp_release(ctx);
return -1;
@@ -151,7 +151,7 @@ enable_sandbox_full(void)
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
return -1;
-
+
// initialize the filter
ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL)
@@ -163,10 +163,10 @@ enable_sandbox_full(void)
ALLOW_RULE(dup2);
ALLOW_RULE(exit);
ALLOW_RULE(exit_group);
- ALLOW_RULE(fcntl);
- ALLOW_RULE(fcntl64);
+ ALLOW_RULE(fcntl);
+ ALLOW_RULE(fcntl64);
ALLOW_RULE(fstat);
- ALLOW_RULE(fstat64);
+ ALLOW_RULE(fstat64);
ALLOW_RULE(getdents);
#ifdef __NR_getdents64
ALLOW_RULE(getdents64);
@@ -176,6 +176,7 @@ enable_sandbox_full(void)
ALLOW_RULE(_llseek);
ALLOW_RULE(lstat);
ALLOW_RULE(lstat64);
+ ALLOW_RULE(madvise);
ALLOW_RULE(mmap);
ALLOW_RULE(mmap2);
ALLOW_RULE(mprotect);
diff --git a/src/softmagic.c b/src/softmagic.c
index 9a5db9d3e2b3d..2edae41df4da3 100644
--- a/src/softmagic.c
+++ b/src/softmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.262 2018/06/22 20:39:50 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.286 2019/05/17 02:24:59 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -45,11 +45,11 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.262 2018/06/22 20:39:50 christos Exp $")
private int match(struct magic_set *, struct magic *, uint32_t,
const struct buffer *, size_t, int, int, int, uint16_t *,
- uint16_t *, int *, int *, int *);
+ uint16_t *, int *, int *, int *, int *);
private int mget(struct magic_set *, struct magic *, const struct buffer *,
- const unsigned char *, size_t,
+ const unsigned char *, size_t,
size_t, unsigned int, int, int, int, uint16_t *,
- uint16_t *, int *, int *, int *);
+ uint16_t *, int *, int *, int *, int *);
private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
const struct buffer *, size_t, unsigned int);
private int magiccheck(struct magic_set *, struct magic *);
@@ -67,24 +67,46 @@ private int cvt_16(union VALUETYPE *, const struct magic *);
private int cvt_32(union VALUETYPE *, const struct magic *);
private int cvt_64(union VALUETYPE *, const struct magic *);
-#define OFFSET_OOB(n, o, i) ((n) < (uint32_t)(o) || (i) > ((n) - (o)))
-#define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
- ((uint64_t)(p)->hq[2]<<40)|((uint64_t)(p)->hq[3]<<32)| \
- ((uint64_t)(p)->hq[4]<<24)|((uint64_t)(p)->hq[5]<<16)| \
- ((uint64_t)(p)->hq[6]<<8)|((uint64_t)(p)->hq[7]))
-#define LE64(p) (((uint64_t)(p)->hq[7]<<56)|((uint64_t)(p)->hq[6]<<48)| \
- ((uint64_t)(p)->hq[5]<<40)|((uint64_t)(p)->hq[4]<<32)| \
- ((uint64_t)(p)->hq[3]<<24)|((uint64_t)(p)->hq[2]<<16)| \
- ((uint64_t)(p)->hq[1]<<8)|((uint64_t)(p)->hq[0]))
-#define LE32(p) (((uint32_t)(p)->hl[3]<<24)|((uint32_t)(p)->hl[2]<<16)| \
- ((uint32_t)(p)->hl[1]<<8)|((uint32_t)(p)->hl[0]))
-#define BE32(p) (((uint32_t)(p)->hl[0]<<24)|((uint32_t)(p)->hl[1]<<16)| \
- ((uint32_t)(p)->hl[2]<<8)|((uint32_t)(p)->hl[3]))
-#define ME32(p) (((uint32_t)(p)->hl[1]<<24)|((uint32_t)(p)->hl[0]<<16)| \
- ((uint32_t)(p)->hl[3]<<8)|((uint32_t)(p)->hl[2]))
-#define BE16(p) (((uint16_t)(p)->hs[0]<<8)|((uint16_t)(p)->hs[1]))
-#define LE16(p) (((uint16_t)(p)->hs[1]<<8)|((uint16_t)(p)->hs[0]))
-#define SEXT(s,v,p) ((s)?(intmax_t)(int##v##_t)(p):(intmax_t)(uint##v##_t)(p))
+#define OFFSET_OOB(n, o, i) ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o)))
+#define BE64(p) ( \
+ (CAST(uint64_t, (p)->hq[0])<<56)| \
+ (CAST(uint64_t, (p)->hq[1])<<48)| \
+ (CAST(uint64_t, (p)->hq[2])<<40)| \
+ (CAST(uint64_t, (p)->hq[3])<<32)| \
+ (CAST(uint64_t, (p)->hq[4])<<24)| \
+ (CAST(uint64_t, (p)->hq[5])<<16)| \
+ (CAST(uint64_t, (p)->hq[6])<<8)| \
+ (CAST(uint64_t, (p)->hq[7])))
+#define LE64(p) ( \
+ (CAST(uint64_t, (p)->hq[7])<<56)| \
+ (CAST(uint64_t, (p)->hq[6])<<48)| \
+ (CAST(uint64_t, (p)->hq[5])<<40)| \
+ (CAST(uint64_t, (p)->hq[4])<<32)| \
+ (CAST(uint64_t, (p)->hq[3])<<24)| \
+ (CAST(uint64_t, (p)->hq[2])<<16)| \
+ (CAST(uint64_t, (p)->hq[1])<<8)| \
+ (CAST(uint64_t, (p)->hq[0])))
+#define LE32(p) ( \
+ (CAST(uint32_t, (p)->hl[3])<<24)| \
+ (CAST(uint32_t, (p)->hl[2])<<16)| \
+ (CAST(uint32_t, (p)->hl[1])<<8)| \
+ (CAST(uint32_t, (p)->hl[0])))
+#define BE32(p) ( \
+ (CAST(uint32_t, (p)->hl[0])<<24)| \
+ (CAST(uint32_t, (p)->hl[1])<<16)| \
+ (CAST(uint32_t, (p)->hl[2])<<8)| \
+ (CAST(uint32_t, (p)->hl[3])))
+#define ME32(p) ( \
+ (CAST(uint32_t, (p)->hl[1])<<24)| \
+ (CAST(uint32_t, (p)->hl[0])<<16)| \
+ (CAST(uint32_t, (p)->hl[3])<<8)| \
+ (CAST(uint32_t, (p)->hl[2])))
+
+#define BE16(p) ((CAST(uint16_t, (p)->hs[0])<<8)|(CAST(uint16_t, (p)->hs[1])))
+#define LE16(p) ((CAST(uint16_t, (p)->hs[1])<<8)|(CAST(uint16_t, (p)->hs[0])))
+#define SEXT(s,v,p) ((s) ? \
+ CAST(intmax_t, CAST(int##v##_t, p)) : \
+ CAST(intmax_t, CAST(uint##v##_t, p)))
/*
* softmagic - lookup one file in parsed, in-memory copy of database
@@ -111,7 +133,7 @@ file_softmagic(struct magic_set *ms, const struct buffer *b,
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, b, 0, mode,
text, 0, indir_count, name_count,
- &printed_something, &need_separator, NULL)) != 0)
+ &printed_something, &need_separator, NULL, NULL)) != 0)
return rv;
return 0;
@@ -125,7 +147,12 @@ private const char * __attribute__((__format_arg__(3)))
file_fmtcheck(struct magic_set *ms, const char *desc, const char *def,
const char *file, size_t line)
{
- const char *ptr = fmtcheck(desc, def);
+ const char *ptr;
+
+ if (strchr(desc, '%') == NULL)
+ return desc;
+
+ ptr = fmtcheck(desc, def);
if (ptr == def)
file_magerror(ms,
"%s, %" SIZE_T_FORMAT "u: format `%s' does not match"
@@ -167,17 +194,25 @@ private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
const struct buffer *b, size_t offset, int mode, int text,
int flip, uint16_t *indir_count, uint16_t *name_count,
- int *printed_something, int *need_separator, int *returnval)
+ int *printed_something, int *need_separator, int *returnval,
+ int *found_match)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
- int returnvalv = 0, e; /* if a match is found it is set to 1*/
+ int found_matchv = 0; /* if a match is found it is set to 1*/
+ int returnvalv = 0, e;
int firstline = 1; /* a flag to print X\n X\n- X */
struct buffer bb;
int print = (ms->flags & MAGIC_NODESC) == 0;
+ /*
+ * returnval can be 0 if a match is found, but there was no
+ * annotation to be printed.
+ */
if (returnval == NULL)
returnval = &returnvalv;
+ if (found_match == NULL)
+ found_match = &found_matchv;
if (file_check_mem(ms, cont_level) == -1)
return -1;
@@ -206,17 +241,21 @@ flush:
ms->line = m->lineno;
/* if main entry matches, print it... */
- switch (mget(ms, m, b, bb.fbuf, bb.flen, offset, cont_level,
+ switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
+ bb.flen, offset, cont_level,
mode, text, flip, indir_count, name_count,
- printed_something, need_separator, returnval)) {
+ printed_something, need_separator, returnval, found_match))
+ {
case -1:
return -1;
case 0:
flush = m->reln != '!';
break;
default:
- if (m->type == FILE_INDIRECT)
+ if (m->type == FILE_INDIRECT) {
+ *found_match = 1;
*returnval = 1;
+ }
switch (magiccheck(ms, m)) {
case -1:
@@ -238,7 +277,11 @@ flush:
goto flush;
}
- if ((e = handle_annotation(ms, m, firstline)) != 0) {
+ if (*m->desc)
+ *found_match = 1;
+
+ if ((e = handle_annotation(ms, m, firstline)) != 0)
+ {
*need_separator = 1;
*printed_something = 1;
*returnval = 1;
@@ -249,16 +292,16 @@ flush:
* If we are going to print something, we'll need to print
* a blank before we print something else.
*/
- if (*m->desc) {
+ if (print && *m->desc) {
*need_separator = 1;
*printed_something = 1;
+ *returnval = 1;
if (print_sep(ms, firstline) == -1)
return -1;
+ if (mprint(ms, m) == -1)
+ return -1;
}
- if (print && mprint(ms, m) == -1)
- return -1;
-
switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
case -1:
case 0:
@@ -299,10 +342,11 @@ flush:
continue;
}
#endif
- switch (mget(ms, m, b, bb.fbuf, bb.flen, offset,
+ switch (mget(ms, m, b, CAST(const unsigned char *,
+ bb.fbuf), bb.flen, offset,
cont_level, mode, text, flip, indir_count,
name_count, printed_something, need_separator,
- returnval)) {
+ returnval, found_match)) {
case -1:
return -1;
case 0:
@@ -311,8 +355,10 @@ flush:
flush = 1;
break;
default:
- if (m->type == FILE_INDIRECT)
+ if (m->type == FILE_INDIRECT) {
+ *found_match = 1;
*returnval = 1;
+ }
flush = 0;
break;
}
@@ -337,6 +383,9 @@ flush:
} else
ms->c.li[cont_level].got_match = 1;
+ if (*m->desc)
+ *found_match = 1;
+
if ((e = handle_annotation(ms, m, firstline))
!= 0) {
*need_separator = 1;
@@ -344,35 +393,36 @@ flush:
*returnval = 1;
return e;
}
- /*
- * If we are going to print something,
- * make sure that we have a separator first.
- */
- if (*m->desc) {
+ if (print && *m->desc) {
+ /*
+ * This continuation matched. Print
+ * its message, with a blank before it
+ * if the previous item printed and
+ * this item isn't empty.
+ */
+ /*
+ * If we are going to print something,
+ * make sure that we have a separator
+ * first.
+ */
if (!*printed_something) {
*printed_something = 1;
if (print_sep(ms, firstline)
== -1)
return -1;
}
- }
- /*
- * This continuation matched. Print
- * its message, with a blank before it
- * if the previous item printed and
- * this item isn't empty.
- */
- /* space if previous printed */
- if (*need_separator
- && ((m->flag & NOSPACE) == 0)
- && *m->desc) {
- if (print &&
- file_printf(ms, " ") == -1)
- return -1;
+ /* space if previous printed */
+ if (*need_separator
+ && (m->flag & NOSPACE) == 0) {
+ if (file_printf(ms, " ") == -1)
+ return -1;
+ }
+ *returnval = 1;
*need_separator = 0;
+ if (mprint(ms, m) == -1)
+ return -1;
+ *need_separator = 1;
}
- if (print && mprint(ms, m) == -1)
- return -1;
switch (moffset(ms, m, &bb,
&ms->c.li[cont_level].off)) {
@@ -385,9 +435,6 @@ flush:
break;
}
- if (*m->desc)
- *need_separator = 1;
-
/*
* If we see any continuations
* at a higher level,
@@ -400,11 +447,13 @@ flush:
}
if (*printed_something) {
firstline = 0;
- if (print)
- *returnval = 1;
}
- if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
+ if (*found_match) {
+ if ((ms->flags & MAGIC_CONTINUE) == 0)
return *returnval; /* don't keep searching */
+ // So that we print a separator
+ *printed_something = 0;
+ firstline = 0;
}
cont_level = 0;
}
@@ -460,7 +509,7 @@ varexpand(struct magic_set *ms, char *buf, size_t len, const char *str)
size_t l;
for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) {
- l = (size_t)(ptr - sptr);
+ l = CAST(size_t, ptr - sptr);
if (l >= len)
return -1;
memcpy(buf, sptr, l);
@@ -526,19 +575,19 @@ mprint(struct magic_set *ms, struct magic *m)
switch (m->type) {
case FILE_BYTE:
- v = file_signextend(ms, m, (uint64_t)p->b);
+ v = file_signextend(ms, m, CAST(uint64_t, p->b));
switch (check_fmt(ms, desc)) {
case -1:
return -1;
case 1:
(void)snprintf(buf, sizeof(buf), "%d",
- (unsigned char)v);
+ CAST(unsigned char, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
if (file_printf(ms, F(ms, desc, "%d"),
- (unsigned char) v) == -1)
+ CAST(unsigned char, v)) == -1)
return -1;
break;
}
@@ -548,19 +597,19 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
- v = file_signextend(ms, m, (uint64_t)p->h);
+ v = file_signextend(ms, m, CAST(uint64_t, p->h));
switch (check_fmt(ms, desc)) {
case -1:
return -1;
case 1:
(void)snprintf(buf, sizeof(buf), "%u",
- (unsigned short)v);
+ CAST(unsigned short, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
if (file_printf(ms, F(ms, desc, "%u"),
- (unsigned short) v) == -1)
+ CAST(unsigned short, v)) == -1)
return -1;
break;
}
@@ -571,17 +620,19 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BELONG:
case FILE_LELONG:
case FILE_MELONG:
- v = file_signextend(ms, m, (uint64_t)p->l);
+ v = file_signextend(ms, m, CAST(uint64_t, p->l));
switch (check_fmt(ms, desc)) {
case -1:
return -1;
case 1:
- (void)snprintf(buf, sizeof(buf), "%u", (uint32_t) v);
+ (void)snprintf(buf, sizeof(buf), "%u",
+ CAST(uint32_t, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, F(ms, desc, "%u"), (uint32_t) v) == -1)
+ if (file_printf(ms, F(ms, desc, "%u"),
+ CAST(uint32_t, v)) == -1)
return -1;
break;
}
@@ -597,13 +648,13 @@ mprint(struct magic_set *ms, struct magic *m)
return -1;
case 1:
(void)snprintf(buf, sizeof(buf), "%" INT64_T_FORMAT "u",
- (unsigned long long)v);
+ CAST(unsigned long long, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
if (file_printf(ms, F(ms, desc, "%" INT64_T_FORMAT "u"),
- (unsigned long long) v) == -1)
+ CAST(unsigned long long, v)) == -1)
return -1;
break;
}
@@ -615,9 +666,9 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BESTRING16:
case FILE_LESTRING16:
if (m->reln == '=' || m->reln == '!') {
- if (file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), m->value.s))
- == -1)
+ if (file_printf(ms, F(ms, desc, "%s"),
+ file_printable(sbuf, sizeof(sbuf), m->value.s,
+ sizeof(m->value.s))) == -1)
return -1;
t = ms->offset + m->vallen;
}
@@ -632,19 +683,20 @@ mprint(struct magic_set *ms, struct magic *m)
if (m->str_flags & STRING_TRIM) {
char *last;
- while (isspace((unsigned char)*str))
+ while (isspace(CAST(unsigned char, *str)))
str++;
last = str;
while (*last)
last++;
--last;
- while (isspace((unsigned char)*last))
+ while (isspace(CAST(unsigned char, *last)))
last--;
*++last = '\0';
}
if (file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), str)) == -1)
+ file_printable(sbuf, sizeof(sbuf), str,
+ sizeof(p->s) - (str - p->s))) == -1)
return -1;
if (m->type == FILE_PSTRING)
@@ -744,13 +796,14 @@ mprint(struct magic_set *ms, struct magic *m)
char *cp;
int rval;
- cp = strndup((const char *)ms->search.s, ms->search.rm_len);
+ cp = strndup(RCAST(const char *, ms->search.s),
+ ms->search.rm_len);
if (cp == NULL) {
file_oomem(ms, ms->search.rm_len);
return -1;
}
rval = file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), cp));
+ file_printable(sbuf, sizeof(sbuf), cp, ms->search.rm_len));
free(cp);
if (rval == -1)
@@ -776,8 +829,9 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset;
break;
case FILE_DER:
- if (file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1)
+ if (file_printf(ms, F(ms, desc, "%s"),
+ file_printable(sbuf, sizeof(sbuf), ms->ms_value.s,
+ sizeof(ms->ms_value.s))) == -1)
return -1;
t = ms->offset;
break;
@@ -785,7 +839,7 @@ mprint(struct magic_set *ms, struct magic *m)
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
return -1;
}
- return (int32_t)t;
+ return CAST(int32_t, t);
}
private int
@@ -832,7 +886,8 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
p->s[strcspn(p->s, "\r\n")] = '\0';
o = CAST(uint32_t, (ms->offset + strlen(p->s)));
if (m->type == FILE_PSTRING)
- o += (uint32_t)file_pstring_length_size(m);
+ o += CAST(uint32_t,
+ file_pstring_length_size(m));
}
break;
@@ -898,11 +953,11 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
case FILE_DER:
{
o = der_offs(ms, m, nbytes);
- if (o == -1 || (size_t)o > nbytes) {
+ if (o == -1 || CAST(size_t, o) > nbytes) {
if ((ms->flags & MAGIC_DEBUG) != 0) {
(void)fprintf(stderr,
- "Bad DER offset %d nbytes=%zu",
- o, nbytes);
+ "Bad DER offset %d nbytes=%"
+ SIZE_T_FORMAT "u", o, nbytes);
}
*op = 0;
return 0;
@@ -915,10 +970,10 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
break;
}
- if ((size_t)o > nbytes) {
+ if (CAST(size_t, o) > nbytes) {
#if 0
- file_error(ms, 0, "Offset out of range %zu > %zu",
- (size_t)o, nbytes);
+ file_error(ms, 0, "Offset out of range %" SIZE_T_FORMAT
+ "u > %" SIZE_T_FORMAT "u", (size_t)o, nbytes);
#endif
return -1;
}
@@ -988,36 +1043,36 @@ cvt_flip(int type, int flip)
return type;
}
}
-#define DO_CVT(fld, cast) \
+#define DO_CVT(fld, type) \
if (m->num_mask) \
switch (m->mask_op & FILE_OPS_MASK) { \
case FILE_OPAND: \
- p->fld &= cast m->num_mask; \
+ p->fld &= CAST(type, m->num_mask); \
break; \
case FILE_OPOR: \
- p->fld |= cast m->num_mask; \
+ p->fld |= CAST(type, m->num_mask); \
break; \
case FILE_OPXOR: \
- p->fld ^= cast m->num_mask; \
+ p->fld ^= CAST(type, m->num_mask); \
break; \
case FILE_OPADD: \
- p->fld += cast m->num_mask; \
+ p->fld += CAST(type, m->num_mask); \
break; \
case FILE_OPMINUS: \
- p->fld -= cast m->num_mask; \
+ p->fld -= CAST(type, m->num_mask); \
break; \
case FILE_OPMULTIPLY: \
- p->fld *= cast m->num_mask; \
+ p->fld *= CAST(type, m->num_mask); \
break; \
case FILE_OPDIVIDE: \
- if (cast m->num_mask == 0) \
+ if (CAST(type, m->num_mask) == 0) \
return -1; \
- p->fld /= cast m->num_mask; \
+ p->fld /= CAST(type, m->num_mask); \
break; \
case FILE_OPMODULO: \
- if (cast m->num_mask == 0) \
+ if (CAST(type, m->num_mask) == 0) \
return -1; \
- p->fld %= cast m->num_mask; \
+ p->fld %= CAST(type, m->num_mask); \
break; \
} \
if (m->mask_op & FILE_OPINVERSE) \
@@ -1026,61 +1081,61 @@ cvt_flip(int type, int flip)
private int
cvt_8(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(b, (uint8_t));
+ DO_CVT(b, uint8_t);
return 0;
}
private int
cvt_16(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(h, (uint16_t));
+ DO_CVT(h, uint16_t);
return 0;
}
private int
cvt_32(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(l, (uint32_t));
+ DO_CVT(l, uint32_t);
return 0;
}
private int
cvt_64(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(q, (uint64_t));
+ DO_CVT(q, uint64_t);
return 0;
}
-#define DO_CVT2(fld, cast) \
+#define DO_CVT2(fld, type) \
if (m->num_mask) \
switch (m->mask_op & FILE_OPS_MASK) { \
case FILE_OPADD: \
- p->fld += cast m->num_mask; \
+ p->fld += CAST(type, m->num_mask); \
break; \
case FILE_OPMINUS: \
- p->fld -= cast m->num_mask; \
+ p->fld -= CAST(type, m->num_mask); \
break; \
case FILE_OPMULTIPLY: \
- p->fld *= cast m->num_mask; \
+ p->fld *= CAST(type, m->num_mask); \
break; \
case FILE_OPDIVIDE: \
- if (cast m->num_mask == 0) \
+ if (CAST(type, m->num_mask) == 0) \
return -1; \
- p->fld /= cast m->num_mask; \
+ p->fld /= CAST(type, m->num_mask); \
break; \
} \
private int
cvt_float(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT2(f, (float));
+ DO_CVT2(f, float);
return 0;
}
private int
cvt_double(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT2(d, (double));
+ DO_CVT2(d, double);
return 0;
}
@@ -1136,7 +1191,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
* string by p->s, so we need to deduct sz.
* Because we can use one of the bytes of the length
* after we shifted as NUL termination.
- */
+ */
len = sz;
}
while (len--)
@@ -1145,14 +1200,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
return 1;
}
case FILE_BESHORT:
- p->h = (short)BE16(p);
+ p->h = CAST(short, BE16(p));
if (cvt_16(p, m) == -1)
goto out;
return 1;
case FILE_BELONG:
case FILE_BEDATE:
case FILE_BELDATE:
- p->l = (int32_t)BE32(p);
+ p->l = CAST(int32_t, BE32(p));
if (cvt_32(p, m) == -1)
goto out;
return 1;
@@ -1160,19 +1215,19 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
case FILE_BEQDATE:
case FILE_BEQLDATE:
case FILE_BEQWDATE:
- p->q = (uint64_t)BE64(p);
+ p->q = CAST(uint64_t, BE64(p));
if (cvt_64(p, m) == -1)
goto out;
return 1;
case FILE_LESHORT:
- p->h = (short)LE16(p);
+ p->h = CAST(short, LE16(p));
if (cvt_16(p, m) == -1)
goto out;
return 1;
case FILE_LELONG:
case FILE_LEDATE:
case FILE_LELDATE:
- p->l = (int32_t)LE32(p);
+ p->l = CAST(int32_t, LE32(p));
if (cvt_32(p, m) == -1)
goto out;
return 1;
@@ -1180,14 +1235,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
case FILE_LEQDATE:
case FILE_LEQLDATE:
case FILE_LEQWDATE:
- p->q = (uint64_t)LE64(p);
+ p->q = CAST(uint64_t, LE64(p));
if (cvt_64(p, m) == -1)
goto out;
return 1;
case FILE_MELONG:
case FILE_MEDATE:
case FILE_MELDATE:
- p->l = (int32_t)ME32(p);
+ p->l = CAST(int32_t, ME32(p));
if (cvt_32(p, m) == -1)
goto out;
return 1;
@@ -1210,7 +1265,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
goto out;
return 1;
case FILE_BEDOUBLE:
- p->q = BE64(p);
+ p->q = BE64(p);
if (cvt_double(p, m) == -1)
goto out;
return 1;
@@ -1301,9 +1356,11 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|| (b = CAST(const char *,
memchr(c, '\r', CAST(size_t, (end - c))))));
lines--, b++) {
- last = b;
if (b < end - 1 && b[0] == '\r' && b[1] == '\n')
b++;
+ if (b < end - 1 && b[0] == '\n')
+ b++;
+ last = b;
}
if (lines)
last = end;
@@ -1366,7 +1423,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
* might even cause problems
*/
if (nbytes < sizeof(*p))
- (void)memset(((char *)(void *)p) + nbytes, '\0',
+ (void)memset(RCAST(char *, RCAST(void *, p)) + nbytes, '\0',
sizeof(*p) - nbytes);
return 0;
}
@@ -1407,7 +1464,7 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off)
if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
- return (uint32_t)offset;
+ return CAST(uint32_t, offset);
}
private int
@@ -1428,19 +1485,19 @@ msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
return -1;
if (o != 0) {
// Not yet!
- file_magerror(ms, "non zero offset %zu at"
- " level %u", o, cont_level);
+ file_magerror(ms, "non zero offset %" SIZE_T_FORMAT
+ "u at level %u", o, cont_level);
return -1;
}
- if ((size_t)-m->offset > b->elen)
+ if (CAST(size_t, -m->offset) > b->elen)
return -1;
- buffer_init(bb, -1, b->ebuf, b->elen);
- ms->eoffset = ms->offset = b->elen + m->offset;
+ buffer_init(bb, -1, NULL, b->ebuf, b->elen);
+ ms->eoffset = ms->offset = CAST(int32_t, b->elen + m->offset);
} else {
if (cont_level == 0) {
normal:
// XXX: Pass real fd, then who frees bb?
- buffer_init(bb, -1, b->fbuf, b->flen);
+ buffer_init(bb, -1, NULL, b->fbuf, b->flen);
ms->offset = m->offset;
ms->eoffset = 0;
} else {
@@ -1448,7 +1505,8 @@ normal:
}
}
if ((ms->flags & MAGIC_DEBUG) != 0) {
- fprintf(stderr, "bb=[%p,%zu], %d [b=%p,%zu], [o=%#x, c=%d]\n",
+ fprintf(stderr, "bb=[%p,%" SIZE_T_FORMAT "u], %d [b=%p,%"
+ SIZE_T_FORMAT "u], [o=%#x, c=%d]\n",
bb->fbuf, bb->flen, ms->offset, b->fbuf, b->flen,
m->offset, cont_level);
}
@@ -1459,7 +1517,8 @@ private int
mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
- int *printed_something, int *need_separator, int *returnval)
+ int *printed_something, int *need_separator, int *returnval,
+ int *found_match)
{
uint32_t offset = ms->offset;
struct buffer bb;
@@ -1484,8 +1543,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
- if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
- (uint32_t)nbytes, m) == -1)
+ if (mcopy(ms, p, m->type, m->flag & INDIR, s,
+ CAST(uint32_t, offset + o), CAST(uint32_t, nbytes), m) == -1)
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
@@ -1494,7 +1553,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
"u, il=%hu, nc=%hu)\n",
m->type, m->flag, offset, o, nbytes,
*indir_count, *name_count);
- mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
+ mdebug(offset, RCAST(char *, RCAST(void *, p)),
+ sizeof(union VALUETYPE));
#ifndef COMPILE_ONLY
file_mdump(m);
#endif
@@ -1505,40 +1565,58 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
const int sgn = m->in_op & FILE_OPSIGNED;
if (m->in_op & FILE_OPINDIRECT) {
const union VALUETYPE *q = CAST(const union VALUETYPE *,
- ((const void *)(s + offset + off)));
- if (OFFSET_OOB(nbytes, offset + off, sizeof(*q)))
- return 0;
+ RCAST(const void *, s + offset + off));
switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
+ if (OFFSET_OOB(nbytes, offset + off, 1))
+ return 0;
off = SEXT(sgn,8,q->b);
break;
case FILE_SHORT:
+ if (OFFSET_OOB(nbytes, offset + off, 2))
+ return 0;
off = SEXT(sgn,16,q->h);
break;
case FILE_BESHORT:
+ if (OFFSET_OOB(nbytes, offset + off, 2))
+ return 0;
off = SEXT(sgn,16,BE16(q));
break;
case FILE_LESHORT:
+ if (OFFSET_OOB(nbytes, offset + off, 2))
+ return 0;
off = SEXT(sgn,16,LE16(q));
break;
case FILE_LONG:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,q->l);
break;
case FILE_BELONG:
case FILE_BEID3:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,BE32(q));
break;
case FILE_LEID3:
case FILE_LELONG:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,LE32(q));
break;
case FILE_MELONG:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,ME32(q));
break;
case FILE_BEQUAD:
+ if (OFFSET_OOB(nbytes, offset + off, 8))
+ return 0;
off = SEXT(sgn,64,BE64(q));
break;
case FILE_LEQUAD:
+ if (OFFSET_OOB(nbytes, offset + off, 8))
+ return 0;
off = SEXT(sgn,64,LE64(q));
break;
default:
@@ -1574,7 +1652,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 0;
lhs = BE32(p);
if (in_type == FILE_BEID3)
- lhs = cvt_id3(ms, (uint32_t)lhs);
+ lhs = cvt_id3(ms, CAST(uint32_t, lhs));
offset = do_ops(m, SEXT(sgn,32,lhs), off);
break;
case FILE_LELONG:
@@ -1583,7 +1661,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 0;
lhs = LE32(p);
if (in_type == FILE_LEID3)
- lhs = cvt_id3(ms, (uint32_t)lhs);
+ lhs = cvt_id3(ms, CAST(uint32_t, lhs));
offset = do_ops(m, SEXT(sgn,32,lhs), off);
break;
case FILE_MELONG:
@@ -1626,7 +1704,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
ms->offset = offset;
if ((ms->flags & MAGIC_DEBUG) != 0) {
- mdebug(offset, (char *)(void *)p,
+ mdebug(offset, RCAST(char *, RCAST(void *, p)),
sizeof(union VALUETYPE));
#ifndef COMPILE_ONLY
file_mdump(m);
@@ -1714,7 +1792,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
if (rv == 1) {
if ((ms->flags & MAGIC_NODESC) == 0 &&
- file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) {
+ file_printf(ms, F(ms, m->desc, "%u"), offset) == -1)
+ {
free(rbuf);
return -1;
}
@@ -1744,7 +1823,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
*need_separator = 0;
rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
mode, text, flip, indir_count, name_count,
- printed_something, need_separator, returnval);
+ printed_something, need_separator, returnval, found_match);
+ (*name_count)--;
if (rv != 1)
*need_separator = oneed_separator;
return rv;
@@ -1775,8 +1855,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
* the ctype functions will work correctly without extra
* casting.
*/
- const unsigned char *a = (const unsigned char *)s1;
- const unsigned char *b = (const unsigned char *)s2;
+ const unsigned char *a = RCAST(const unsigned char *, s1);
+ const unsigned char *b = RCAST(const unsigned char *, s2);
const unsigned char *eb = b + len;
uint64_t v;
@@ -1971,13 +2051,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_STRING:
case FILE_PSTRING:
l = 0;
- v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+ v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen),
+ m->str_flags);
break;
case FILE_BESTRING16:
case FILE_LESTRING16:
l = 0;
- v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+ v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen),
+ m->str_flags);
break;
case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
@@ -1990,6 +2072,22 @@ magiccheck(struct magic_set *ms, struct magic *m)
slen = MIN(m->vallen, sizeof(m->value.s));
l = 0;
v = 0;
+#ifdef HAVE_MEMMEM
+ if (slen > 0 && m->str_flags == 0) {
+ const char *found;
+ idx = m->str_range + slen;
+ if (m->str_range == 0 || ms->search.s_len < idx)
+ idx = ms->search.s_len;
+ found = CAST(const char *, memmem(ms->search.s, idx,
+ m->value.s, slen));
+ if (!found)
+ return 0;
+ idx = found - ms->search.s;
+ ms->search.offset += idx;
+ ms->search.rm_len = ms->search.s_len - idx;
+ break;
+ }
+#endif
for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
if (slen + idx > ms->search.s_len)
@@ -2019,7 +2117,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
if (rc) {
file_regerror(&rx, rc, ms);
- v = (uint64_t)-1;
+ v = CAST(uint64_t, -1);
} else {
regmatch_t pmatch;
size_t slen = ms->search.s_len;
@@ -2040,15 +2138,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
search = CCAST(char *, "");
copy = NULL;
}
- rc = file_regexec(&rx, (const char *)search,
+ rc = file_regexec(&rx, RCAST(const char *, search),
1, &pmatch, 0);
free(copy);
switch (rc) {
case 0:
- ms->search.s += (int)pmatch.rm_so;
- ms->search.offset += (size_t)pmatch.rm_so;
- ms->search.rm_len =
- (size_t)(pmatch.rm_eo - pmatch.rm_so);
+ ms->search.s += CAST(int, pmatch.rm_so);
+ ms->search.offset += CAST(size_t, pmatch.rm_so);
+ ms->search.rm_len = CAST(size_t,
+ pmatch.rm_eo - pmatch.rm_so);
v = 0;
break;
@@ -2058,12 +2156,12 @@ magiccheck(struct magic_set *ms, struct magic *m)
default:
file_regerror(&rx, rc, ms);
- v = (uint64_t)-1;
+ v = CAST(uint64_t, -1);
break;
}
}
file_regfree(&rx);
- if (v == (uint64_t)-1)
+ if (v == CAST(uint64_t, -1))
return -1;
break;
}
@@ -2092,7 +2190,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
case 'x':
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
- "u == *any* = 1\n", (unsigned long long)v);
+ "u == *any* = 1\n", CAST(unsigned long long, v));
matched = 1;
break;
@@ -2100,16 +2198,18 @@ magiccheck(struct magic_set *ms, struct magic *m)
matched = v != l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
- INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
- (unsigned long long)l, matched);
+ INT64_T_FORMAT "u = %d\n",
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
break;
case '=':
matched = v == l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
- INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
- (unsigned long long)l, matched);
+ INT64_T_FORMAT "u = %d\n",
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
break;
case '>':
@@ -2118,15 +2218,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"u > %" INT64_T_FORMAT "u = %d\n",
- (unsigned long long)v,
- (unsigned long long)l, matched);
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
}
else {
- matched = (int64_t) v > (int64_t) l;
+ matched = CAST(int64_t, v) > CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"d > %" INT64_T_FORMAT "d = %d\n",
- (long long)v, (long long)l, matched);
+ CAST(long long, v),
+ CAST(long long, l), matched);
}
break;
@@ -2136,15 +2237,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"u < %" INT64_T_FORMAT "u = %d\n",
- (unsigned long long)v,
- (unsigned long long)l, matched);
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
}
else {
- matched = (int64_t) v < (int64_t) l;
+ matched = CAST(int64_t, v) < CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"d < %" INT64_T_FORMAT "d = %d\n",
- (long long)v, (long long)l, matched);
+ CAST(long long, v),
+ CAST(long long, l), matched);
}
break;
@@ -2153,8 +2255,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
INT64_T_FORMAT "x) == %" INT64_T_FORMAT
- "x) = %d\n", (unsigned long long)v,
- (unsigned long long)l, (unsigned long long)l,
+ "x) = %d\n", CAST(unsigned long long, v),
+ CAST(unsigned long long, l),
+ CAST(unsigned long long, l),
matched);
break;
@@ -2163,9 +2266,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
INT64_T_FORMAT "x) != %" INT64_T_FORMAT
- "x) = %d\n", (unsigned long long)v,
- (unsigned long long)l, (unsigned long long)l,
- matched);
+ "x) = %d\n", CAST(unsigned long long, v),
+ CAST(unsigned long long, l),
+ CAST(unsigned long long, l), matched);
break;
default:
@@ -2181,14 +2284,14 @@ private int
handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
{
if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
- if (!firstline && file_printf(ms, "\n- ") == -1)
+ if (print_sep(ms, firstline) == -1)
return -1;
if (file_printf(ms, "%.8s", m->apple) == -1)
return -1;
return 1;
}
if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) {
- if (!firstline && file_printf(ms, "\n- ") == -1)
+ if (print_sep(ms, firstline) == -1)
return -1;
if (file_printf(ms, "%s", m->ext) == -1)
return -1;
@@ -2197,7 +2300,7 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
char buf[1024];
const char *p;
- if (!firstline && file_printf(ms, "\n- ") == -1)
+ if (print_sep(ms, firstline) == -1)
return -1;
if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1)
p = m->mimetype;
@@ -2213,13 +2316,11 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
private int
print_sep(struct magic_set *ms, int firstline)
{
-// if (ms->flags & MAGIC_NODESC)
-// return 0;
if (firstline)
return 0;
/*
* we found another match
* put a newline and '-' to do some simple formatting
*/
- return file_printf(ms, "\n- ");
+ return file_separator(ms);
}
diff --git a/src/vasprintf.c b/src/vasprintf.c
index ad1d3165534de..c87465bd53488 100644
--- a/src/vasprintf.c
+++ b/src/vasprintf.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 AUTHOR 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
@@ -51,7 +51,7 @@ 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. The name of the author may not be used to
endorse or promote products derived from this software without specific
-prior written permission.
+prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -108,7 +108,7 @@ you use strange formats.
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: vasprintf.c,v 1.14 2017/08/13 00:21:47 christos Exp $")
+FILE_RCSID("@(#)$File: vasprintf.c,v 1.16 2018/10/01 18:45:39 christos Exp $")
#endif /* lint */
#include <assert.h>
@@ -116,12 +116,8 @@ FILE_RCSID("@(#)$File: vasprintf.c,v 1.14 2017/08/13 00:21:47 christos Exp $")
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif
-#ifdef HAVE_STDDEF_H
#include <stddef.h>
-#endif
#define ALLOC_CHUNK 2048
#define ALLOC_SECURITY_MARGIN 1024 /* big value because some platforms have very big 'G' exponent */