diff options
author | obrien <obrien@FreeBSD.org> | 2009-01-02 02:57:16 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2009-01-02 02:57:16 +0000 |
commit | 05dd1f1bd993ec12015e6782ea5c46b6a0b69ecb (patch) | |
tree | 2238cf9e0926a037b65f3101d96555426a07c999 /softmagic.c | |
parent | 87d6fde760865f6a73395e6a7a56b3a608ea99b1 (diff) | |
download | FreeBSD-src-05dd1f1bd993ec12015e6782ea5c46b6a0b69ecb.zip FreeBSD-src-05dd1f1bd993ec12015e6782ea5c46b6a0b69ecb.tar.gz |
Virgin import of Christos Zoulas's FILE 4.26.
Diffstat (limited to 'softmagic.c')
-rw-r--r-- | softmagic.c | 191 |
1 files changed, 99 insertions, 92 deletions
diff --git a/softmagic.c b/softmagic.c index 21a0148..39a7fc8 100644 --- a/softmagic.c +++ b/softmagic.c @@ -38,11 +38,11 @@ #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.103 2007/12/27 16:35:59 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.120 2008/07/28 17:25:21 christos Exp $") #endif /* lint */ private int match(struct magic_set *, struct magic *, uint32_t, - const unsigned char *, size_t); + const unsigned char *, size_t, int); private int mget(struct magic_set *, const unsigned char *, struct magic *, size_t, unsigned int); private int magiccheck(struct magic_set *, struct magic *); @@ -58,17 +58,23 @@ private void cvt_32(union VALUETYPE *, const struct magic *); private void cvt_64(union VALUETYPE *, const struct magic *); /* + * Macro to give description string according to whether we want plain + * text or MIME type + */ +#define MAGIC_DESC ((ms->flags & MAGIC_MIME) ? m->mimetype : m->desc) + +/* * softmagic - lookup one file in parsed, in-memory copy of database * Passed the name and FILE * of one file to be typed. */ /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ protected int -file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes) +file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, int mode) { struct mlist *ml; int rv; for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next) - if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes)) != 0) + if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode)) != 0) return rv; return 0; @@ -103,7 +109,7 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes) */ private int match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, - const unsigned char *s, size_t nbytes) + const unsigned char *s, size_t nbytes, int mode) { uint32_t magindex = 0; unsigned int cont_level = 0; @@ -117,17 +123,26 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, for (magindex = 0; magindex < nmagic; magindex++) { int flush; + struct magic *m = &magic[magindex]; - ms->offset = magic[magindex].offset; - ms->line = magic[magindex].lineno; + if ((m->flag & BINTEST) != mode) { + /* Skip sub-tests */ + while (magic[magindex + 1].cont_level != 0 && + ++magindex < nmagic) + continue; + continue; /* Skip to next top-level test*/ + } + + ms->offset = m->offset; + ms->line = m->lineno; /* if main entry matches, print it... */ - flush = !mget(ms, s, &magic[magindex], nbytes, cont_level); + flush = !mget(ms, s, m, nbytes, cont_level); if (flush) { - if (magic[magindex].reln == '!') + if (m->reln == '!') flush = 0; } else { - switch (magiccheck(ms, &magic[magindex])) { + switch (magiccheck(ms, m)) { case -1: return -1; case 0: @@ -152,15 +167,14 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, * If we are going to print something, we'll need to print * a blank before we print something else. */ - if (magic[magindex].desc[0]) { + if (*MAGIC_DESC) { need_separator = 1; printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; } - if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) - == -1) + if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1) return -1; /* and any continuations that match */ @@ -169,36 +183,36 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, while (magic[magindex+1].cont_level != 0 && ++magindex < nmagic) { - ms->line = magic[magindex].lineno; /* for messages */ + m = &magic[magindex]; + ms->line = m->lineno; /* for messages */ - if (cont_level < magic[magindex].cont_level) + if (cont_level < m->cont_level) continue; - if (cont_level > magic[magindex].cont_level) { + if (cont_level > m->cont_level) { /* * We're at the end of the level * "cont_level" continuations. */ - cont_level = magic[magindex].cont_level; + cont_level = m->cont_level; } - ms->offset = magic[magindex].offset; - if (magic[magindex].flag & OFFADD) { + ms->offset = m->offset; + if (m->flag & OFFADD) { ms->offset += ms->c.li[cont_level - 1].off; } #ifdef ENABLE_CONDITIONALS - if (magic[magindex].cond == COND_ELSE || - magic[magindex].cond == COND_ELIF) { + if (m->cond == COND_ELSE || + m->cond == COND_ELIF) { if (ms->c.li[cont_level].last_match == 1) continue; } #endif - flush = !mget(ms, s, &magic[magindex], nbytes, - cont_level); - if (flush && magic[magindex].reln != '!') + flush = !mget(ms, s, m, nbytes, cont_level); + if (flush && m->reln != '!') continue; - switch (flush ? 1 : magiccheck(ms, &magic[magindex])) { + switch (flush ? 1 : magiccheck(ms, m)) { case -1: return -1; case 0: @@ -210,7 +224,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, #ifdef ENABLE_CONDITIONALS ms->c.li[cont_level].last_match = 1; #endif - if (magic[magindex].type != FILE_DEFAULT) + if (m->type != FILE_DEFAULT) ms->c.li[cont_level].got_match = 1; else if (ms->c.li[cont_level].got_match) { ms->c.li[cont_level].got_match = 0; @@ -220,7 +234,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, * If we are going to print something, * make sure that we have a separator first. */ - if (magic[magindex].desc[0]) { + if (*MAGIC_DESC) { printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; @@ -233,15 +247,15 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, */ /* space if previous printed */ if (need_separator - && (magic[magindex].nospflag == 0) - && (magic[magindex].desc[0] != '\0')) { + && ((m->flag & NOSPACE) == 0) + && *MAGIC_DESC) { if (file_printf(ms, " ") == -1) return -1; need_separator = 0; } - if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) == -1) + if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1) return -1; - if (magic[magindex].desc[0]) + if (*MAGIC_DESC) need_separator = 1; /* @@ -271,7 +285,7 @@ check_fmt(struct magic_set *ms, struct magic *m) regex_t rx; int rc; - if (strchr(m->desc, '%') == NULL) + if (strchr(MAGIC_DESC, '%') == NULL) return 0; rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB); @@ -281,7 +295,7 @@ check_fmt(struct magic_set *ms, struct magic *m) file_magerror(ms, "regex error %d, (%s)", rc, errmsg); return -1; } else { - rc = regexec(&rx, m->desc, 0, 0, 0); + rc = regexec(&rx, MAGIC_DESC, 0, 0, 0); regfree(&rx); return !rc; } @@ -314,7 +328,7 @@ mprint(struct magic_set *ms, struct magic *m) float vf; double vd; int64_t t = 0; - char buf[512]; + char *buf; union VALUETYPE *p = &ms->ms_value; switch (m->type) { @@ -324,14 +338,13 @@ mprint(struct magic_set *ms, struct magic *m) case -1: return -1; case 1: - if (snprintf(buf, sizeof(buf), "%c", - (unsigned char)v) < 0) + if (asprintf(&buf, "%c", (unsigned char)v) < 0) return -1; - if (file_printf(ms, m->desc, buf) == -1) + if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: - if (file_printf(ms, m->desc, (unsigned char) v) == -1) + if (file_printf(ms, MAGIC_DESC, (unsigned char) v) == -1) return -1; break; } @@ -346,14 +359,13 @@ mprint(struct magic_set *ms, struct magic *m) case -1: return -1; case 1: - if (snprintf(buf, sizeof(buf), "%hu", - (unsigned short)v) < 0) + if (asprintf(&buf, "%hu", (unsigned short)v) < 0) return -1; - if (file_printf(ms, m->desc, buf) == -1) + if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: - if (file_printf(ms, m->desc, (unsigned short) v) == -1) + if (file_printf(ms, MAGIC_DESC, (unsigned short) v) == -1) return -1; break; } @@ -369,13 +381,13 @@ mprint(struct magic_set *ms, struct magic *m) case -1: return -1; case 1: - if (snprintf(buf, sizeof(buf), "%u", (uint32_t)v) < 0) + if (asprintf(&buf, "%u", (uint32_t)v) < 0) return -1; - if (file_printf(ms, m->desc, buf) == -1) + if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: - if (file_printf(ms, m->desc, (uint32_t) v) == -1) + if (file_printf(ms, MAGIC_DESC, (uint32_t) v) == -1) return -1; break; } @@ -386,7 +398,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEQUAD: case FILE_LEQUAD: v = file_signextend(ms, m, p->q); - if (file_printf(ms, m->desc, (uint64_t) v) == -1) + if (file_printf(ms, MAGIC_DESC, (uint64_t) v) == -1) return -1; t = ms->offset + sizeof(int64_t); break; @@ -396,16 +408,18 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BESTRING16: case FILE_LESTRING16: if (m->reln == '=' || m->reln == '!') { - if (file_printf(ms, m->desc, m->value.s) == -1) + if (file_printf(ms, MAGIC_DESC, m->value.s) == -1) return -1; t = ms->offset + m->vallen; } else { if (*m->value.s == '\0') p->s[strcspn(p->s, "\n")] = '\0'; - if (file_printf(ms, m->desc, p->s) == -1) + if (file_printf(ms, MAGIC_DESC, p->s) == -1) return -1; t = ms->offset + strlen(p->s); + if (m->type == FILE_PSTRING) + t++; } break; @@ -413,7 +427,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: - if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1) + if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 1)) == -1) return -1; t = ms->offset + sizeof(time_t); break; @@ -422,7 +436,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: - if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1) + if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 0)) == -1) return -1; t = ms->offset + sizeof(time_t); break; @@ -430,7 +444,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_QDATE: case FILE_BEQDATE: case FILE_LEQDATE: - if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 1)) + if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 1)) == -1) return -1; t = ms->offset + sizeof(uint64_t); @@ -439,7 +453,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_QLDATE: case FILE_BEQLDATE: case FILE_LEQLDATE: - if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 0)) + if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 0)) == -1) return -1; t = ms->offset + sizeof(uint64_t); @@ -453,13 +467,13 @@ mprint(struct magic_set *ms, struct magic *m) case -1: return -1; case 1: - if (snprintf(buf, sizeof(buf), "%g", vf) < 0) + if (asprintf(&buf, "%g", vf) < 0) return -1; - if (file_printf(ms, m->desc, buf) == -1) + if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: - if (file_printf(ms, m->desc, vf) == -1) + if (file_printf(ms, MAGIC_DESC, vf) == -1) return -1; break; } @@ -474,13 +488,13 @@ mprint(struct magic_set *ms, struct magic *m) case -1: return -1; case 1: - if (snprintf(buf, sizeof(buf), "%g", vd) < 0) + if (asprintf(&buf, "%g", vd) < 0) return -1; - if (file_printf(ms, m->desc, buf) == -1) + if (file_printf(ms, MAGIC_DESC, buf) == -1) return -1; break; default: - if (file_printf(ms, m->desc, vd) == -1) + if (file_printf(ms, MAGIC_DESC, vd) == -1) return -1; break; } @@ -496,7 +510,7 @@ mprint(struct magic_set *ms, struct magic *m) file_oomem(ms, ms->search.rm_len); return -1; } - rval = file_printf(ms, m->desc, cp); + rval = file_printf(ms, MAGIC_DESC, cp); free(cp); if (rval == -1) @@ -510,7 +524,7 @@ mprint(struct magic_set *ms, struct magic *m) } case FILE_SEARCH: - if (file_printf(ms, m->desc, m->value.s) == -1) + if (file_printf(ms, MAGIC_DESC, m->value.s) == -1) return -1; if ((m->str_flags & REGEX_OFFSET_START)) t = ms->search.offset; @@ -519,7 +533,7 @@ mprint(struct magic_set *ms, struct magic *m) break; case FILE_DEFAULT: - if (file_printf(ms, m->desc, m->value.s) == -1) + if (file_printf(ms, MAGIC_DESC, m->value.s) == -1) return -1; t = ms->offset; break; @@ -646,13 +660,14 @@ mconvert(struct magic_set *ms, struct magic *m) case FILE_STRING: case FILE_BESTRING16: case FILE_LESTRING16: { - size_t len; - /* Null terminate and eat *trailing* return */ p->s[sizeof(p->s) - 1] = '\0'; +#if 0 + /* Why? breaks magic numbers that end with \xa */ len = strlen(p->s); if (len-- && p->s[len] == '\n') p->s[len] = '\0'; +#endif return 1; } case FILE_PSTRING: { @@ -663,9 +678,12 @@ mconvert(struct magic_set *ms, struct magic *m) while (len--) *ptr1++ = *ptr2++; *ptr1 = '\0'; +#if 0 + /* Why? breaks magic numbers that end with \xa */ len = strlen(p->s); if (len-- && p->s[len] == '\n') p->s[len] = '\0'; +#endif return 1; } case FILE_BESHORT: @@ -682,10 +700,11 @@ mconvert(struct magic_set *ms, struct magic *m) case FILE_BEQUAD: case FILE_BEQDATE: case FILE_BEQLDATE: - p->q = (int64_t) - (((int64_t)p->hq[0]<<56)|((int64_t)p->hq[1]<<48)| - ((int64_t)p->hq[2]<<40)|((int64_t)p->hq[3]<<32)| - (p->hq[4]<<24)|(p->hq[5]<<16)|(p->hq[6]<<8)|(p->hq[7])); + p->q = (uint64_t) + (((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])); cvt_64(p, m); return 1; case FILE_LESHORT: @@ -702,10 +721,11 @@ mconvert(struct magic_set *ms, struct magic *m) case FILE_LEQUAD: case FILE_LEQDATE: case FILE_LEQLDATE: - p->q = (int64_t) - (((int64_t)p->hq[7]<<56)|((int64_t)p->hq[6]<<48)| - ((int64_t)p->hq[5]<<40)|((int64_t)p->hq[4]<<32)| - (p->hq[3]<<24)|(p->hq[2]<<16)|(p->hq[1]<<8)|(p->hq[0])); + p->q = (uint64_t) + (((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])); cvt_64(p, m); return 1; case FILE_MELONG: @@ -778,13 +798,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, case FILE_SEARCH: ms->search.s = (const char *)s + offset; ms->search.s_len = nbytes - offset; + ms->search.offset = offset; return 0; case FILE_REGEX: { - /* - * offset is interpreted as last line to search, - * (starting at 1), not as bytes-from start-of-file - */ const char *b; const char *c; const char *last; /* end of search region */ @@ -879,7 +896,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, size_t nbytes, unsigned int cont_level) { uint32_t offset = ms->offset; - uint32_t count = m->str_count; + uint32_t count = m->str_range; union VALUETYPE *p = &ms->ms_value; if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1) @@ -893,8 +910,8 @@ mget(struct magic_set *ms, const unsigned char *s, if (m->flag & INDIR) { int off = m->in_offset; if (m->in_op & FILE_OPINDIRECT) { - const union VALUETYPE *q = - ((const void *)(s + offset + off)); + const union VALUETYPE *q = CAST(const union VALUETYPE *, + ((const void *)(s + offset + off))); switch (m->in_type) { case FILE_BYTE: off = q->b; @@ -1340,13 +1357,6 @@ mget(struct magic_set *ms, const unsigned char *s, case FILE_OPMODULO: offset = p->l % off; break; - /* case TOOMANYSWITCHBLOCKS: - * ugh = p->eye % m->strain; - * rub; - * case BEER: - * off = p->tab & m->in_gest; - * sleep; - */ } } else offset = p->l; @@ -1443,10 +1453,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags) uint64_t v; /* - * What we want here is: - * v = strncmp(m->value.s, p->s, m->vallen); - * but ignoring any nulls. bcmp doesn't give -/+/0 - * and isn't universally available anyway. + * What we want here is v = strncmp(s1, s2, len), + * but ignoring any nulls. */ v = 0; if (0L == flags) { /* normal string: do it fast */ @@ -1646,15 +1654,14 @@ magiccheck(struct magic_set *ms, struct magic *m) slen = MIN(m->vallen, sizeof(m->value.s)); l = 0; v = 0; - ms->search.offset = m->offset; - for (idx = 0; m->str_count == 0 || idx < m->str_count; idx++) { + for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) { if (slen + idx > ms->search.s_len) break; v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags); if (v == 0) { /* found match */ - ms->search.offset = m->offset + idx; + ms->search.offset += idx; break; } } |