summaryrefslogtreecommitdiff
path: root/usr.bin/file/softmagic.c
diff options
context:
space:
mode:
authorCharles Longeau <chl@cvs.openbsd.org>2009-04-24 18:54:35 +0000
committerCharles Longeau <chl@cvs.openbsd.org>2009-04-24 18:54:35 +0000
commit8dcb5d1d2940d843dabdcef31bc8cb2dba817119 (patch)
tree7458bf3b9120705a836b9e56b7925dce2cf42159 /usr.bin/file/softmagic.c
parenta75d7de4707e3d43e0e869059021172cadecca54 (diff)
file update to 4.24
The '-i' switch is now enabled so file(1) can output mime type strings. ok ian@ builk ports build test on amd64 by jasper@ ok ray@ gilles@ on a almost identical diff builk ports build test on sparc64 on this almost identical diff by ajacoutot@ also tested by landry@
Diffstat (limited to 'usr.bin/file/softmagic.c')
-rw-r--r--usr.bin/file/softmagic.c367
1 files changed, 278 insertions, 89 deletions
diff --git a/usr.bin/file/softmagic.c b/usr.bin/file/softmagic.c
index 701ebe41646..5290b613334 100644
--- a/usr.bin/file/softmagic.c
+++ b/usr.bin/file/softmagic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softmagic.c,v 1.13 2008/05/08 01:40:56 chl Exp $ */
+/* $OpenBSD: softmagic.c,v 1.14 2009/04/24 18:54:34 chl Exp $ */
/*
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
@@ -39,11 +39,11 @@
#ifndef lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.13 2008/05/08 01:40:56 chl Exp $")
+FILE_RCSID("@(#)$Id: softmagic.c,v 1.14 2009/04/24 18:54:34 chl 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 *);
@@ -59,17 +59,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;
@@ -104,7 +110,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;
@@ -118,17 +124,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];
+
+ 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 = magic[magindex].offset;
- ms->line = magic[magindex].lineno;
+ 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:
@@ -153,15 +168,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 */
@@ -170,36 +184,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:
@@ -211,7 +225,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;
@@ -221,7 +235,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;
@@ -234,15 +248,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;
/*
@@ -255,9 +269,10 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
}
}
- firstline = 0;
- if (printed_something)
+ if (printed_something) {
+ firstline = 0;
returnval = 1;
+ }
if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
return 1; /* don't keep searching */
}
@@ -271,7 +286,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 +296,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;
}
@@ -311,8 +326,10 @@ private int32_t
mprint(struct magic_set *ms, struct magic *m)
{
uint64_t v;
+ float vf;
+ double vd;
int64_t t = 0;
- char buf[512];
+ char *buf;
union VALUETYPE *p = &ms->ms_value;
switch (m->type) {
@@ -322,14 +339,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;
}
@@ -344,14 +360,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;
}
@@ -367,13 +382,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;
}
@@ -384,7 +399,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;
@@ -394,16 +409,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;
@@ -411,7 +428,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;
@@ -420,7 +437,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;
@@ -428,7 +445,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);
@@ -437,12 +454,54 @@ 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);
break;
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ vf = p->f;
+ switch (check_fmt(ms, m)) {
+ case -1:
+ return -1;
+ case 1:
+ if (asprintf(&buf, "%g", vf) < 0)
+ return -1;
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
+ return -1;
+ break;
+ default:
+ if (file_printf(ms, MAGIC_DESC, vf) == -1)
+ return -1;
+ break;
+ }
+ t = ms->offset + sizeof(float);
+ break;
+
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ vd = p->d;
+ switch (check_fmt(ms, m)) {
+ case -1:
+ return -1;
+ case 1:
+ if (asprintf(&buf, "%g", vd) < 0)
+ return -1;
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
+ return -1;
+ break;
+ default:
+ if (file_printf(ms, MAGIC_DESC, vd) == -1)
+ return -1;
+ break;
+ }
+ t = ms->offset + sizeof(double);
+ break;
+
case FILE_REGEX: {
char *cp;
int rval;
@@ -452,7 +511,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)
@@ -466,7 +525,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;
@@ -475,7 +534,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;
@@ -543,6 +602,35 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
DO_CVT(q, (uint64_t));
}
+#define DO_CVT2(fld, cast) \
+ if (m->num_mask) \
+ switch (m->mask_op & FILE_OPS_MASK) { \
+ case FILE_OPADD: \
+ p->fld += cast m->num_mask; \
+ break; \
+ case FILE_OPMINUS: \
+ p->fld -= cast m->num_mask; \
+ break; \
+ case FILE_OPMULTIPLY: \
+ p->fld *= cast m->num_mask; \
+ break; \
+ case FILE_OPDIVIDE: \
+ p->fld /= cast m->num_mask; \
+ break; \
+ } \
+
+private void
+cvt_float(union VALUETYPE *p, const struct magic *m)
+{
+ DO_CVT2(f, (float));
+}
+
+private void
+cvt_double(union VALUETYPE *p, const struct magic *m)
+{
+ DO_CVT2(d, (double));
+}
+
/*
* Convert the byte order of the data we are looking at
* While we're here, let's apply the mask operation
@@ -609,10 +697,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:
@@ -629,10 +718,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:
@@ -642,6 +732,36 @@ mconvert(struct magic_set *ms, struct magic *m)
((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));
cvt_32(p, m);
return 1;
+ case FILE_FLOAT:
+ cvt_float(p, m);
+ return 1;
+ case FILE_BEFLOAT:
+ p->l = ((uint32_t)p->hl[0]<<24)|((uint32_t)p->hl[1]<<16)|
+ ((uint32_t)p->hl[2]<<8) |((uint32_t)p->hl[3]);
+ cvt_float(p, m);
+ return 1;
+ case FILE_LEFLOAT:
+ p->l = ((uint32_t)p->hl[3]<<24)|((uint32_t)p->hl[2]<<16)|
+ ((uint32_t)p->hl[1]<<8) |((uint32_t)p->hl[0]);
+ cvt_float(p, m);
+ return 1;
+ case FILE_DOUBLE:
+ cvt_double(p, m);
+ return 1;
+ case FILE_BEDOUBLE:
+ p->q = ((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_double(p, m);
+ return 1;
+ case FILE_LEDOUBLE:
+ p->q = ((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_double(p, m);
+ return 1;
case FILE_REGEX:
case FILE_SEARCH:
case FILE_DEFAULT:
@@ -675,13 +795,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 */
@@ -728,13 +845,17 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
offset);
return -1;
}
- for (/*EMPTY*/; src < esrc; src++, dst++) {
+ for (/*EMPTY*/; src < esrc; src += 2, dst++) {
if (dst < edst)
- *dst = *src++;
+ *dst = *src;
else
break;
- if (*dst == '\0')
- *dst = ' ';
+ if (*dst == '\0') {
+ if (type == FILE_BESTRING16 ?
+ *(src - 1) != '\0' :
+ *(src + 1) != '\0')
+ *dst = ' ';
+ }
}
*edst = '\0';
return 0;
@@ -772,7 +893,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)
@@ -1233,13 +1354,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;
@@ -1287,10 +1401,20 @@ mget(struct magic_set *ms, const unsigned char *s,
case FILE_BELDATE:
case FILE_LELDATE:
case FILE_MELDATE:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
if (nbytes < (offset + 4))
return 0;
break;
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ if (nbytes < (offset + 8))
+ return 0;
+ break;
+
case FILE_STRING:
case FILE_PSTRING:
case FILE_SEARCH:
@@ -1326,10 +1450,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 */
@@ -1393,6 +1515,8 @@ magiccheck(struct magic_set *ms, struct magic *m)
{
uint64_t l = m->value.q;
uint64_t v;
+ float fl, fv;
+ double dl, dv;
int matched;
union VALUETYPE *p = &ms->ms_value;
@@ -1434,6 +1558,72 @@ magiccheck(struct magic_set *ms, struct magic *m)
v = p->q;
break;
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ fl = m->value.f;
+ fv = p->f;
+ switch (m->reln) {
+ case 'x':
+ matched = 1;
+ break;
+
+ case '!':
+ matched = fv != fl;
+ break;
+
+ case '=':
+ matched = fv == fl;
+ break;
+
+ case '>':
+ matched = fv > fl;
+ break;
+
+ case '<':
+ matched = fv < fl;
+ break;
+
+ default:
+ matched = 0;
+ file_magerror(ms, "cannot happen with float: invalid relation `%c'", m->reln);
+ return -1;
+ }
+ return matched;
+
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ dl = m->value.d;
+ dv = p->d;
+ switch (m->reln) {
+ case 'x':
+ matched = 1;
+ break;
+
+ case '!':
+ matched = dv != dl;
+ break;
+
+ case '=':
+ matched = dv == dl;
+ break;
+
+ case '>':
+ matched = dv > dl;
+ break;
+
+ case '<':
+ matched = dv < dl;
+ break;
+
+ default:
+ matched = 0;
+ file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln);
+ return -1;
+ }
+ return matched;
+
case FILE_DEFAULT:
l = 0;
v = 0;
@@ -1461,15 +1651,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;
}
}