summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristos Zoulas <christos@zoulas.com>2007-11-08 00:31:37 +0000
committerChristos Zoulas <christos@zoulas.com>2007-11-08 00:31:37 +0000
commit41b716d047cc61522770090157ca207dbcade41e (patch)
treea49e0d03bb652a275a01c051adcb45f92938538c /src
parente0d26fb3276d881211945647dc6e6192da52dba8 (diff)
downloadfile-git-41b716d047cc61522770090157ca207dbcade41e.tar.gz
float and double formats from behanw@websterwood.com (Behan Webster)
Diffstat (limited to 'src')
-rw-r--r--src/apprentice.c73
-rw-r--r--src/file.h14
-rw-r--r--src/print.c12
-rw-r--r--src/softmagic.c183
4 files changed, 277 insertions, 5 deletions
diff --git a/src/apprentice.c b/src/apprentice.c
index c421b2ac..8b12853a 100644
--- a/src/apprentice.c
+++ b/src/apprentice.c
@@ -46,7 +46,7 @@
#endif
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.106 2007/10/23 19:58:59 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.107 2007/11/08 00:31:37 christos Exp $")
#endif /* lint */
#define EATAB {while (isascii((unsigned char) *l) && \
@@ -188,6 +188,12 @@ static const struct type_tbl_s {
{ XX("qldate"), FILE_QLDATE, FILE_FMT_STR },
{ XX("leqldate"), FILE_LEQLDATE, FILE_FMT_STR },
{ XX("beqldate"), FILE_BEQLDATE, FILE_FMT_STR },
+ { XX("float"), FILE_FLOAT, FILE_FMT_FLOAT },
+ { XX("befloat"), FILE_BEFLOAT, FILE_FMT_FLOAT },
+ { XX("lefloat"), FILE_LEFLOAT, FILE_FMT_FLOAT },
+ { XX("double"), FILE_DOUBLE, FILE_FMT_DOUBLE },
+ { XX("bedouble"), FILE_BEDOUBLE, FILE_FMT_DOUBLE },
+ { XX("ledouble"), FILE_LEDOUBLE, FILE_FMT_DOUBLE },
{ XX_NULL, FILE_INVALID, FILE_FMT_NONE },
# undef XX
# undef XX_NULL
@@ -432,6 +438,9 @@ apprentice_magic_strength(const struct magic *m)
case FILE_LELDATE:
case FILE_BELDATE:
case FILE_MELDATE:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
val += 4 * MULT;
break;
@@ -444,6 +453,9 @@ apprentice_magic_strength(const struct magic *m)
case FILE_QLDATE:
case FILE_LEQLDATE:
case FILE_BEQLDATE:
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
val += 8 * MULT;
break;
@@ -647,6 +659,9 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_BELONG:
case FILE_LELONG:
case FILE_MELONG:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
v = (int32_t) v;
break;
case FILE_QUAD:
@@ -658,6 +673,9 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_BEQLDATE:
case FILE_LEQDATE:
case FILE_LEQLDATE:
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
v = (int64_t) v;
break;
case FILE_STRING:
@@ -960,6 +978,16 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
case 'B':
m->in_type = FILE_BYTE;
break;
+ case 'e':
+ case 'f':
+ case 'g':
+ m->in_type = FILE_LEDOUBLE;
+ break;
+ case 'E':
+ case 'F':
+ case 'G':
+ m->in_type = FILE_BEDOUBLE;
+ break;
default:
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@@ -1253,6 +1281,31 @@ check_format_type(const char *ptr, int type)
return -1;
}
+ case FILE_FMT_FLOAT:
+ case FILE_FMT_DOUBLE:
+ if (*ptr == '-')
+ ptr++;
+ if (*ptr == '.')
+ ptr++;
+ while (isdigit((unsigned char)*ptr)) ptr++;
+ if (*ptr == '.')
+ ptr++;
+ while (isdigit((unsigned char)*ptr)) ptr++;
+
+ switch (*ptr++) {
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ return 0;
+
+ default:
+ return -1;
+ }
+
+
case FILE_FMT_STR:
if (*ptr == '-')
ptr++;
@@ -1359,6 +1412,24 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
}
m->vallen = slen;
return 0;
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ if (m->reln != 'x') {
+ char *ep;
+ m->value.f = strtof(*p, &ep);
+ *p = ep;
+ }
+ return 0;
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ if (m->reln != 'x') {
+ char *ep;
+ m->value.d = strtod(*p, &ep);
+ *p = ep;
+ }
+ return 0;
default:
if (m->reln != 'x') {
char *ep;
diff --git a/src/file.h b/src/file.h
index cc8b4d29..ce0f4e26 100644
--- a/src/file.h
+++ b/src/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.91 2007/03/25 03:13:47 christos Exp $
+ * @(#)$File: file.h,v 1.92 2007/11/08 00:31:37 christos Exp $
*/
#ifndef __file_h__
@@ -146,7 +146,13 @@ struct magic {
#define FILE_QLDATE 30
#define FILE_LEQLDATE 31
#define FILE_BEQLDATE 32
-#define FILE_NAMES_SIZE 33/* size of array to contain all names */
+#define FILE_FLOAT 33
+#define FILE_BEFLOAT 34
+#define FILE_LEFLOAT 35
+#define FILE_DOUBLE 36
+#define FILE_BEDOUBLE 37
+#define FILE_LEDOUBLE 38
+#define FILE_NAMES_SIZE 39/* size of array to contain all names */
#define IS_STRING(t) \
((t) == FILE_STRING || \
@@ -161,6 +167,8 @@ struct magic {
#define FILE_FMT_NUM 1 /* "cduxXi" */
#define FILE_FMT_STR 2 /* "s" */
#define FILE_FMT_QUAD 3 /* "ll" */
+#define FILE_FMT_FLOAT 4 /* "eEfFgG" */
+#define FILE_FMT_DOUBLE 5 /* "eEfFgG" */
/* Word 3 */
uint8_t in_op; /* operator for indirection */
@@ -224,6 +232,8 @@ struct magic {
uint8_t hl[4]; /* 4 bytes of a fixed-endian "long" */
uint8_t hq[8]; /* 8 bytes of a fixed-endian "quad" */
char s[MAXstring]; /* the search string or regex pattern */
+ float f;
+ double d;
} value; /* either number or string */
/* Words 17..31 */
char desc[MAXDESC]; /* description */
diff --git a/src/print.c b/src/print.c
index d1d1ec10..d41bb739 100644
--- a/src/print.c
+++ b/src/print.c
@@ -41,7 +41,7 @@
#include <time.h>
#ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.59 2007/03/05 02:41:29 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.60 2007/11/08 00:31:37 christos Exp $")
#endif /* lint */
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
@@ -157,6 +157,16 @@ file_mdump(struct magic *m)
(void)fprintf(stderr, "%s,",
file_fmttime((uint32_t)m->value.q, 0));
break;
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ (void) fprintf(stderr, "%G", m->value.f);
+ break;
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ (void) fprintf(stderr, "%G", m->value.d);
+ break;
case FILE_DEFAULT:
/* XXX - do anything here? */
break;
diff --git a/src/softmagic.c b/src/softmagic.c
index efa63e94..ba2faa38 100644
--- a/src/softmagic.c
+++ b/src/softmagic.c
@@ -38,7 +38,7 @@
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.101 2007/10/17 19:33:31 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.102 2007/11/08 00:31:37 christos Exp $")
#endif /* lint */
private int match(struct magic_set *, struct magic *, uint32_t,
@@ -311,6 +311,8 @@ 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];
union VALUETYPE *p = &ms->ms_value;
@@ -446,6 +448,48 @@ mprint(struct magic_set *ms, struct magic *m)
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 (snprintf(buf, sizeof(buf), "%g", vf) < 0)
+ return -1;
+ if (file_printf(ms, m->desc, buf) == -1)
+ return -1;
+ break;
+ default:
+ if (file_printf(ms, m->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 (snprintf(buf, sizeof(buf), "%g", vd) < 0)
+ return -1;
+ if (file_printf(ms, m->desc, buf) == -1)
+ return -1;
+ break;
+ default:
+ if (file_printf(ms, m->desc, vd) == -1)
+ return -1;
+ break;
+ }
+ t = ms->offset + sizeof(double);
+ break;
+
case FILE_REGEX: {
char *cp;
int rval;
@@ -546,6 +590,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
@@ -645,6 +718,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:
@@ -1294,10 +1397,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:
@@ -1400,6 +1513,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;
@@ -1441,6 +1556,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;