summaryrefslogtreecommitdiffstats
path: root/contrib/file/softmagic.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/file/softmagic.c')
-rw-r--r--contrib/file/softmagic.c861
1 files changed, 487 insertions, 374 deletions
diff --git a/contrib/file/softmagic.c b/contrib/file/softmagic.c
index d1ef94d..4e063b9 100644
--- a/contrib/file/softmagic.c
+++ b/contrib/file/softmagic.c
@@ -1,31 +1,41 @@
/*
+ * 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Ian F. Darwin and others.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/*
* softmagic - interpret variable magic from MAGIC
- *
- * Copyright (c) Ian F. Darwin, 1987.
- * Written by Ian F. Darwin.
- *
- * This software is not subject to any license of the American Telephone
- * and Telegraph Company or of the Regents of the University of California.
- *
- * Permission is granted to anyone to use this software for any purpose on
- * any computer system, and to alter it and redistribute it freely, subject
- * to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of this
- * software, no matter how awful, even if they arise from flaws in it.
- *
- * 2. The origin of this software must not be misrepresented, either by
- * explicit claim or by omission. Since few users ever read sources,
- * credits must appear in the documentation.
- *
- * 3. Altered versions must be plainly marked as such, and must not be
- * misrepresented as being the original software. Since few users
- * ever read sources, credits must appear in the documentation.
- *
- * 4. This notice may not be removed or altered.
*/
#include "file.h"
+#include "magic.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
@@ -34,17 +44,18 @@
#ifndef lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.54 2003/02/25 13:04:32 christos Exp $")
+FILE_RCSID("@(#)$Id: softmagic.c,v 1.66 2004/07/24 20:38:56 christos Exp $")
#endif /* lint */
-static int match(struct magic *, uint32_t, unsigned char *, int);
-static int mget(union VALUETYPE *, unsigned char *, struct magic *, int);
-static int mcheck(union VALUETYPE *, struct magic *);
-static int32_t mprint(union VALUETYPE *, struct magic *);
-static void mdebug(int32_t, char *, int);
-static int mconvert(union VALUETYPE *, struct magic *);
-
-extern int kflag;
+private int match(struct magic_set *, struct magic *, uint32_t,
+ const unsigned char *, size_t);
+private int mget(struct magic_set *, union VALUETYPE *, const unsigned char *,
+ struct magic *, size_t);
+private int mcheck(struct magic_set *, union VALUETYPE *, struct magic *);
+private int32_t mprint(struct magic_set *, union VALUETYPE *, struct magic *);
+private void mdebug(uint32_t, const char *, size_t);
+private int mconvert(struct magic_set *, union VALUETYPE *, struct magic *);
+private int check_mem(struct magic_set *, unsigned int);
/*
* softmagic - lookup one file in database
@@ -52,13 +63,12 @@ extern int kflag;
* Passed the name and FILE * of one file to be typed.
*/
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
-int
-softmagic(unsigned char *buf, int nbytes)
+protected int
+file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
{
struct mlist *ml;
-
- for (ml = mlist.next; ml != &mlist; ml = ml->next)
- if (match(ml->magic, ml->nmagic, buf, nbytes))
+ for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
+ if (match(ms, ml->magic, ml->nmagic, buf, nbytes))
return 1;
return 0;
@@ -91,44 +101,53 @@ softmagic(unsigned char *buf, int nbytes)
* If a continuation matches, we bump the current continuation level
* so that higher-level continuations are processed.
*/
-static int
-match(struct magic *magic, uint32_t nmagic, unsigned char *s, int nbytes)
+private int
+match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
+ const unsigned char *s, size_t nbytes)
{
- int magindex = 0;
- int cont_level = 0;
+ uint32_t magindex = 0;
+ unsigned int cont_level = 0;
int need_separator = 0;
union VALUETYPE p;
- static int32_t *tmpoff = NULL;
- static size_t tmplen = 0;
int32_t oldoff = 0;
int returnval = 0; /* if a match is found it is set to 1*/
int firstline = 1; /* a flag to print X\n X\n- X */
- if (tmpoff == NULL)
- if ((tmpoff = (int32_t *) malloc(
- (tmplen = 20) * sizeof(*tmpoff))) == NULL)
- error("out of memory\n");
+ if (check_mem(ms, cont_level) == -1)
+ return -1;
for (magindex = 0; magindex < nmagic; magindex++) {
/* if main entry matches, print it... */
- if (!mget(&p, s, &magic[magindex], nbytes) ||
- !mcheck(&p, &magic[magindex])) {
- /*
- * main entry didn't match,
- * flush its continuations
- */
- while (magindex < nmagic &&
- magic[magindex + 1].cont_level != 0)
- magindex++;
- continue;
+ int flush = !mget(ms, &p, s, &magic[magindex], nbytes);
+ switch (mcheck(ms, &p, &magic[magindex])) {
+ case -1:
+ return -1;
+ case 0:
+ flush++;
+ break;
+ default:
+ break;
+ }
+ if (flush) {
+ /*
+ * main entry didn't match,
+ * flush its continuations
+ */
+ while (magindex < nmagic - 1 &&
+ magic[magindex + 1].cont_level != 0)
+ magindex++;
+ continue;
}
- if (! firstline) { /* we found another match */
+ if (!firstline) { /* we found another match */
/* put a newline and '-' to do some simple formatting*/
- printf("\n- ");
+ if (file_printf(ms, "\n- ") == -1)
+ return -1;
}
- tmpoff[cont_level] = mprint(&p, &magic[magindex]);
+ if ((ms->c.off[cont_level] = mprint(ms, &p, &magic[magindex]))
+ == -1)
+ return -1;
/*
* If we printed something, we'll need to print
* a blank before we print something else.
@@ -136,107 +155,130 @@ match(struct magic *magic, uint32_t nmagic, unsigned char *s, int nbytes)
if (magic[magindex].desc[0])
need_separator = 1;
/* and any continuations that match */
- if (++cont_level >= tmplen)
- if ((tmpoff = (int32_t *) realloc(tmpoff,
- (tmplen += 20) * sizeof(*tmpoff))) == NULL)
- error("out of memory\n");
+ if (check_mem(ms, ++cont_level) == -1)
+ return -1;
+
while (magic[magindex+1].cont_level != 0 &&
++magindex < nmagic) {
- if (cont_level >= magic[magindex].cont_level) {
- if (cont_level > magic[magindex].cont_level) {
- /*
- * We're at the end of the level
- * "cont_level" continuations.
- */
- cont_level = magic[magindex].cont_level;
- }
- if (magic[magindex].flag & OFFADD) {
- oldoff=magic[magindex].offset;
- magic[magindex].offset +=
- tmpoff[cont_level-1];
+ if (cont_level < magic[magindex].cont_level)
+ continue;
+ if (cont_level > magic[magindex].cont_level) {
+ /*
+ * We're at the end of the level
+ * "cont_level" continuations.
+ */
+ cont_level = magic[magindex].cont_level;
+ }
+ if (magic[magindex].flag & OFFADD) {
+ oldoff=magic[magindex].offset;
+ magic[magindex].offset += ms->c.off[cont_level-1];
+ }
+ if (!mget(ms, &p, s, &magic[magindex], nbytes))
+ goto done;
+
+ switch (mcheck(ms, &p, &magic[magindex])) {
+ case -1:
+ return -1;
+ case 0:
+ break;
+ default:
+ /*
+ * 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
+ && (magic[magindex].nospflag == 0)
+ && (magic[magindex].desc[0] != '\0')) {
+ if (file_printf(ms, " ") == -1)
+ return -1;
+ need_separator = 0;
}
- if (mget(&p, s, &magic[magindex], nbytes) &&
- mcheck(&p, &magic[magindex])) {
- /*
- * 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
- && (magic[magindex].nospflag == 0)
- && (magic[magindex].desc[0] != '\0')
- ) {
- (void) putchar(' ');
- need_separator = 0;
- }
- tmpoff[cont_level] =
- mprint(&p, &magic[magindex]);
- if (magic[magindex].desc[0])
- need_separator = 1;
+ if ((ms->c.off[cont_level] = mprint(ms, &p,
+ &magic[magindex])) == -1)
+ return -1;
+ if (magic[magindex].desc[0])
+ need_separator = 1;
- /*
- * If we see any continuations
- * at a higher level,
- * process them.
- */
- if (++cont_level >= tmplen)
- if ((tmpoff =
- (int32_t *) realloc(tmpoff,
- (tmplen += 20)
- * sizeof(*tmpoff))) == NULL)
- error("out of memory\n");
- }
- if (magic[magindex].flag & OFFADD) {
- magic[magindex].offset = oldoff;
- }
+ /*
+ * If we see any continuations
+ * at a higher level,
+ * process them.
+ */
+ if (check_mem(ms, ++cont_level) == -1)
+ return -1;
+ }
+done:
+ if (magic[magindex].flag & OFFADD) {
+ magic[magindex].offset = oldoff;
}
}
firstline = 0;
returnval = 1;
- if (!kflag) {
+ if ((ms->flags & MAGIC_CONTINUE) == 0) {
return 1; /* don't keep searching */
}
}
return returnval; /* This is hit if -k is set or there is no match */
}
-static int32_t
-mprint(union VALUETYPE *p, struct magic *m)
+private int
+check_mem(struct magic_set *ms, unsigned int level)
+{
+ size_t len;
+
+ if (level < ms->c.len)
+ return 0;
+
+ len = (ms->c.len += 20) * sizeof(*ms->c.off);
+ ms->c.off = (ms->c.off == NULL) ? malloc(len) : realloc(ms->c.off, len);
+ if (ms->c.off != NULL)
+ return 0;
+ file_oomem(ms);
+ return -1;
+}
+
+private int32_t
+mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
{
uint32_t v;
int32_t t=0 ;
switch (m->type) {
- case BYTE:
- v = signextend(m, p->b);
- (void) printf(m->desc, (unsigned char) v);
+ case FILE_BYTE:
+ v = file_signextend(ms, m, (size_t)p->b);
+ if (file_printf(ms, m->desc, (unsigned char) v) == -1)
+ return -1;
t = m->offset + sizeof(char);
break;
- case SHORT:
- case BESHORT:
- case LESHORT:
- v = signextend(m, p->h);
- (void) printf(m->desc, (unsigned short) v);
+ case FILE_SHORT:
+ case FILE_BESHORT:
+ case FILE_LESHORT:
+ v = file_signextend(ms, m, (size_t)p->h);
+ if (file_printf(ms, m->desc, (unsigned short) v) == -1)
+ return -1;
t = m->offset + sizeof(short);
break;
- case LONG:
- case BELONG:
- case LELONG:
- v = signextend(m, p->l);
- (void) printf(m->desc, (uint32_t) v);
+ case FILE_LONG:
+ case FILE_BELONG:
+ case FILE_LELONG:
+ v = file_signextend(ms, m, p->l);
+ if (file_printf(ms, m->desc, (uint32_t) v) == -1)
+ return -1;
t = m->offset + sizeof(int32_t);
break;
- case STRING:
- case PSTRING:
+ case FILE_STRING:
+ case FILE_PSTRING:
if (m->reln == '=') {
- (void) printf(m->desc, m->value.s);
+ if (file_printf(ms, m->desc, m->value.s) == -1)
+ return -1;
t = m->offset + strlen(m->value.s);
}
else {
@@ -245,32 +287,36 @@ mprint(union VALUETYPE *p, struct magic *m)
if (cp)
*cp = '\0';
}
- (void) printf(m->desc, p->s);
+ if (file_printf(ms, m->desc, p->s) == -1)
+ return -1;
t = m->offset + strlen(p->s);
}
break;
- case DATE:
- case BEDATE:
- case LEDATE:
- (void) printf(m->desc, fmttime(p->l, 1));
+ case FILE_DATE:
+ case FILE_BEDATE:
+ case FILE_LEDATE:
+ if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1)
+ return -1;
t = m->offset + sizeof(time_t);
break;
- case LDATE:
- case BELDATE:
- case LELDATE:
- (void) printf(m->desc, fmttime(p->l, 0));
+ case FILE_LDATE:
+ case FILE_BELDATE:
+ case FILE_LELDATE:
+ if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1)
+ return -1;
t = m->offset + sizeof(time_t);
break;
- case REGEX:
- (void) printf(m->desc, p->s);
+ case FILE_REGEX:
+ if (file_printf(ms, m->desc, p->s) == -1)
+ return -1;
t = m->offset + strlen(p->s);
break;
default:
- error("invalid m->type (%d) in mprint().\n", m->type);
- /*NOTREACHED*/
+ file_error(ms, 0, "invalid m->type (%d) in mprint()", m->type);
+ return -1;
}
return(t);
}
@@ -280,106 +326,106 @@ mprint(union VALUETYPE *p, struct magic *m)
* While we're here, let's apply the mask operation
* (unless you have a better idea)
*/
-static int
-mconvert(union VALUETYPE *p, struct magic *m)
+private int
+mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
{
switch (m->type) {
- case BYTE:
+ case FILE_BYTE:
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->b &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->b |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->b ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->b += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->b -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->b *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->b /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->b %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->b = ~p->b;
return 1;
- case SHORT:
+ case FILE_SHORT:
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->h &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->h |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->h ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->h += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->h -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->h *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->h /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->h %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->h = ~p->h;
return 1;
- case LONG:
- case DATE:
- case LDATE:
+ case FILE_LONG:
+ case FILE_DATE:
+ case FILE_LDATE:
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->l &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->l |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->l ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->l += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->l -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->l *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->l /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->l %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->l = ~p->l;
return 1;
- case STRING:
+ case FILE_STRING:
{
int n;
@@ -390,10 +436,10 @@ mconvert(union VALUETYPE *p, struct magic *m)
p->s[n] = '\0';
return 1;
}
- case PSTRING:
+ case FILE_PSTRING:
{
char *ptr1 = p->s, *ptr2 = ptr1 + 1;
- int n = *p->s;
+ unsigned int n = *p->s;
if (n >= sizeof(p->s))
n = sizeof(p->s) - 1;
while (n--)
@@ -404,175 +450,180 @@ mconvert(union VALUETYPE *p, struct magic *m)
p->s[n] = '\0';
return 1;
}
- case BESHORT:
+ case FILE_BESHORT:
p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->h &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->h |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->h ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->h += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->h -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->h *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->h /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->h %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->h = ~p->h;
return 1;
- case BELONG:
- case BEDATE:
- case BELDATE:
+ case FILE_BELONG:
+ case FILE_BEDATE:
+ case FILE_BELDATE:
p->l = (int32_t)
((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->l &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->l |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->l ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->l += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->l -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->l *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->l /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->l %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->l = ~p->l;
return 1;
- case LESHORT:
+ case FILE_LESHORT:
p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->h &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->h |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->h ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->h += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->h -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->h *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->h /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->h %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->h = ~p->h;
return 1;
- case LELONG:
- case LEDATE:
- case LELDATE:
+ case FILE_LELONG:
+ case FILE_LEDATE:
+ case FILE_LELDATE:
p->l = (int32_t)
((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
if (m->mask)
switch (m->mask_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
p->l &= m->mask;
break;
- case OPOR:
+ case FILE_OPOR:
p->l |= m->mask;
break;
- case OPXOR:
+ case FILE_OPXOR:
p->l ^= m->mask;
break;
- case OPADD:
+ case FILE_OPADD:
p->l += m->mask;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
p->l -= m->mask;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
p->l *= m->mask;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
p->l /= m->mask;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
p->l %= m->mask;
break;
}
- if (m->mask_op & OPINVERSE)
+ if (m->mask_op & FILE_OPINVERSE)
p->l = ~p->l;
return 1;
- case REGEX:
+ case FILE_REGEX:
return 1;
default:
- error("invalid type %d in mconvert().\n", m->type);
+ file_error(ms, 0, "invalid type %d in mconvert()", m->type);
return 0;
}
}
-static void
-mdebug(int32_t offset, char *str, int len)
+private void
+mdebug(uint32_t offset, const char *str, size_t len)
{
(void) fprintf(stderr, "mget @%d: ", offset);
- showstr(stderr, (char *) str, len);
+ file_showstr(stderr, str, len);
(void) fputc('\n', stderr);
(void) fputc('\n', stderr);
}
-static int
-mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes)
+private int
+mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
+ struct magic *m, size_t nbytes)
{
- int32_t offset = m->offset;
+ uint32_t offset = m->offset;
- if (m->type == REGEX) {
- /*
- * offset is interpreted as last line to search,
- * (starting at 1), not as bytes-from start-of-file
- */
- unsigned char *last = NULL;
- p->buf = (char *)s;
- for (; offset && (s = (unsigned char *)strchr(s, '\n')) != NULL;
- offset--, s++)
- last = s;
- if (last != NULL)
- *last = '\0';
+ if (m->type == FILE_REGEX) {
+ /*
+ * offset is interpreted as last line to search,
+ * (starting at 1), not as bytes-from start-of-file
+ */
+ unsigned char *b, *last = NULL;
+ if ((p->buf = strdup((const char *)s)) == NULL) {
+ file_oomem(ms);
+ return -1;
+ }
+ for (b = (unsigned char *)p->buf; offset &&
+ (b = (unsigned char *)strchr((char *)b, '\n')) != NULL;
+ offset--, s++)
+ last = b;
+ if (last != NULL)
+ *last = '\0';
} else if (offset + sizeof(union VALUETYPE) <= nbytes)
memcpy(p, s + offset, sizeof(union VALUETYPE));
else {
@@ -580,228 +631,272 @@ mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes)
* the usefulness of padding with zeroes eludes me, it
* might even cause problems
*/
- int32_t have = nbytes - offset;
memset(p, 0, sizeof(union VALUETYPE));
- if (have > 0)
- memcpy(p, s + offset, have);
+ if (offset < nbytes)
+ memcpy(p, s + offset, nbytes - offset);
}
- if (debug) {
- mdebug(offset, (char *) p, sizeof(union VALUETYPE));
- mdump(m);
+ /* Verify we have enough data to match magic type */
+ switch (m->type) {
+ case FILE_BYTE:
+ if (nbytes < (offset + 1)) /* should alway be true */
+ return 0;
+ break;
+
+ case FILE_SHORT:
+ case FILE_BESHORT:
+ case FILE_LESHORT:
+ if (nbytes < (offset + 2))
+ return 0;
+ break;
+
+ case FILE_LONG:
+ case FILE_BELONG:
+ case FILE_LELONG:
+ case FILE_DATE:
+ case FILE_BEDATE:
+ case FILE_LEDATE:
+ case FILE_LDATE:
+ case FILE_BELDATE:
+ case FILE_LELDATE:
+ if (nbytes < (offset + 4))
+ return 0;
+ break;
+
+ case FILE_STRING:
+ case FILE_PSTRING:
+ if (nbytes < (offset + m->vallen))
+ return 0;
+ break;
+ }
+
+ if ((ms->flags & MAGIC_DEBUG) != 0) {
+ mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
+ file_mdump(m);
}
if (m->flag & INDIR) {
switch (m->in_type) {
- case BYTE:
- if (m->in_offset)
+ case FILE_BYTE:
+ if (m->in_offset) {
switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_OPAND:
offset = p->b & m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = p->b | m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = p->b ^ m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = p->b + m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = p->b - m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = p->b * m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = p->b / m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = p->b % m->in_offset;
break;
}
- if (m->in_op & OPINVERSE)
+ } else
+ offset = p->b;
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
- case BESHORT:
- if (m->in_offset)
- switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_BESHORT:
+ if (m->in_offset) {
+ switch (m->in_op & 0x7F) {
+ case FILE_OPAND:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) &
m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) |
m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) ^
m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) +
m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) -
m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) *
m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) /
m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) %
m->in_offset;
break;
}
- if (m->in_op & OPINVERSE)
+ } else
+ offset = (short)((p->hs[0]<<8)|
+ (p->hs[1]));
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
- case LESHORT:
- if (m->in_offset)
- switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_LESHORT:
+ if (m->in_offset) {
+ switch (m->in_op & 0x7F) {
+ case FILE_OPAND:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) &
m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) |
m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) ^
m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) +
m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) -
m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) *
m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) /
m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) %
m->in_offset;
break;
}
- if (m->in_op & OPINVERSE)
+ } else
+ offset = (short)((p->hs[1]<<8)|
+ (p->hs[0]));
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
- case SHORT:
- if (m->in_offset)
- switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_SHORT:
+ if (m->in_offset) {
+ switch (m->in_op & 0x7F) {
+ case FILE_OPAND:
offset = p->h & m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = p->h | m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = p->h ^ m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = p->h + m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = p->h - m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = p->h * m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = p->h / m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = p->h % m->in_offset;
break;
}
- if (m->in_op & OPINVERSE)
+ }
+ else
+ offset = p->h;
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
- case BELONG:
- if (m->in_offset)
- switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_BELONG:
+ if (m->in_offset) {
+ switch (m->in_op & 0x7F) {
+ case FILE_OPAND:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) &
m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) |
m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) ^
m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) +
m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) -
m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) *
m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
(p->hl[3])) /
m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
(p->hl[2]<<8)|
@@ -809,62 +904,67 @@ mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes)
m->in_offset;
break;
}
- if (m->in_op & OPINVERSE)
+ } else
+ offset = (int32_t)((p->hl[0]<<24)|
+ (p->hl[1]<<16)|
+ (p->hl[2]<<8)|
+ (p->hl[3]));
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
- case LELONG:
- if (m->in_offset)
- switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_LELONG:
+ if (m->in_offset) {
+ switch (m->in_op & 0x7F) {
+ case FILE_OPAND:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) &
m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) |
m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) ^
m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) +
m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) -
m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) *
m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
(p->hl[0])) /
m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
(p->hl[1]<<8)|
@@ -872,34 +972,39 @@ mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes)
m->in_offset;
break;
}
- if (m->in_op & OPINVERSE)
+ } else
+ offset = (int32_t)((p->hl[3]<<24)|
+ (p->hl[2]<<16)|
+ (p->hl[1]<<8)|
+ (p->hl[0]));
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
- case LONG:
- if (m->in_offset)
- switch (m->in_op&0x7F) {
- case OPAND:
+ case FILE_LONG:
+ if (m->in_offset) {
+ switch (m->in_op & 0x7F) {
+ case FILE_OPAND:
offset = p->l & m->in_offset;
break;
- case OPOR:
+ case FILE_OPOR:
offset = p->l | m->in_offset;
break;
- case OPXOR:
+ case FILE_OPXOR:
offset = p->l ^ m->in_offset;
break;
- case OPADD:
+ case FILE_OPADD:
offset = p->l + m->in_offset;
break;
- case OPMINUS:
+ case FILE_OPMINUS:
offset = p->l - m->in_offset;
break;
- case OPMULTIPLY:
+ case FILE_OPMULTIPLY:
offset = p->l * m->in_offset;
break;
- case OPDIVIDE:
+ case FILE_OPDIVIDE:
offset = p->l / m->in_offset;
break;
- case OPMODULO:
+ case FILE_OPMODULO:
offset = p->l % m->in_offset;
break;
/* case TOOMANYSWITCHBLOCKS:
@@ -910,64 +1015,67 @@ mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes)
* sleep;
*/
}
- if (m->in_op & OPINVERSE)
+ } else
+ offset = p->l;
+ if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
break;
}
- if (offset + sizeof(union VALUETYPE) > nbytes)
+ if (nbytes < sizeof(union VALUETYPE) ||
+ nbytes - sizeof(union VALUETYPE) < offset)
return 0;
memcpy(p, s + offset, sizeof(union VALUETYPE));
- if (debug) {
- mdebug(offset, (char *) p, sizeof(union VALUETYPE));
- mdump(m);
+ if ((ms->flags & MAGIC_DEBUG) != 0) {
+ mdebug(offset, (char *)(void *)p,
+ sizeof(union VALUETYPE));
+ file_mdump(m);
}
}
- if (!mconvert(p, m))
+ if (!mconvert(ms, p, m))
return 0;
return 1;
}
-static int
-mcheck(union VALUETYPE *p, struct magic *m)
+private int
+mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
{
uint32_t l = m->value.l;
uint32_t v;
int matched;
if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
- fprintf(stderr, "BOINK");
return 1;
}
switch (m->type) {
- case BYTE:
+ case FILE_BYTE:
v = p->b;
break;
- case SHORT:
- case BESHORT:
- case LESHORT:
+ case FILE_SHORT:
+ case FILE_BESHORT:
+ case FILE_LESHORT:
v = p->h;
break;
- case LONG:
- case BELONG:
- case LELONG:
- case DATE:
- case BEDATE:
- case LEDATE:
- case LDATE:
- case BELDATE:
- case LELDATE:
+ case FILE_LONG:
+ case FILE_BELONG:
+ case FILE_LELONG:
+ case FILE_DATE:
+ case FILE_BEDATE:
+ case FILE_LEDATE:
+ case FILE_LDATE:
+ case FILE_BELDATE:
+ case FILE_LELDATE:
v = p->l;
break;
- case STRING:
- case PSTRING:
+ case FILE_STRING:
+ case FILE_PSTRING:
{
/*
* What we want here is:
@@ -1013,7 +1121,7 @@ mcheck(union VALUETYPE *p, struct magic *m)
}
break;
}
- case REGEX:
+ case FILE_REGEX:
{
int rc;
regex_t rx;
@@ -1021,38 +1129,42 @@ mcheck(union VALUETYPE *p, struct magic *m)
rc = regcomp(&rx, m->value.s, REG_EXTENDED|REG_NOSUB);
if (rc) {
+ free(p->buf);
regerror(rc, &rx, errmsg, sizeof(errmsg));
- error("regex error %d, (%s)\n", rc, errmsg);
+ file_error(ms, 0, "regex error %d, (%s)", rc, errmsg);
+ return -1;
} else {
rc = regexec(&rx, p->buf, 0, 0, 0);
+ regfree(&rx);
+ free(p->buf);
return !rc;
}
}
default:
- error("invalid type %d in mcheck().\n", m->type);
- return 0;/*NOTREACHED*/
+ file_error(ms, 0, "invalid type %d in mcheck()", m->type);
+ return -1;
}
- if(m->type != STRING && m->type != PSTRING)
- v = signextend(m, v);
+ if (m->type != FILE_STRING && m->type != FILE_PSTRING)
+ v = file_signextend(ms, m, v);
switch (m->reln) {
case 'x':
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%u == *any* = 1\n", v);
matched = 1;
break;
case '!':
matched = v != l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%u != %u = %d\n",
v, l, matched);
break;
case '=':
matched = v == l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%u == %u = %d\n",
v, l, matched);
break;
@@ -1060,13 +1172,13 @@ mcheck(union VALUETYPE *p, struct magic *m)
case '>':
if (m->flag & UNSIGNED) {
matched = v > l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%u > %u = %d\n",
v, l, matched);
}
else {
matched = (int32_t) v > (int32_t) l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%d > %d = %d\n",
v, l, matched);
}
@@ -1075,13 +1187,13 @@ mcheck(union VALUETYPE *p, struct magic *m)
case '<':
if (m->flag & UNSIGNED) {
matched = v < l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%u < %u = %d\n",
v, l, matched);
}
else {
matched = (int32_t) v < (int32_t) l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%d < %d = %d\n",
v, l, matched);
}
@@ -1089,22 +1201,23 @@ mcheck(union VALUETYPE *p, struct magic *m)
case '&':
matched = (v & l) == l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%x & %x) == %x) = %d\n",
v, l, l, matched);
break;
case '^':
matched = (v & l) != l;
- if (debug)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%x & %x) != %x) = %d\n",
v, l, l, matched);
break;
default:
matched = 0;
- error("mcheck: can't happen: invalid relation %d.\n", m->reln);
- break;/*NOTREACHED*/
+ file_error(ms, 0, "cannot happen: invalid relation `%c'",
+ m->reln);
+ return -1;
}
return matched;
OpenPOWER on IntegriCloud