diff options
Diffstat (limited to 'src/softmagic.c')
| -rw-r--r-- | src/softmagic.c | 469 |
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); } |
