summaryrefslogtreecommitdiff
path: root/src/softmagic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/softmagic.c')
-rw-r--r--src/softmagic.c469
1 files changed, 285 insertions, 184 deletions
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);
}