summaryrefslogtreecommitdiff
path: root/src/softmagic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/softmagic.c')
-rw-r--r--src/softmagic.c835
1 files changed, 370 insertions, 465 deletions
diff --git a/src/softmagic.c b/src/softmagic.c
index 5e277e3..b9e9753 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.206 2015/01/01 17:07:34 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -41,28 +41,46 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.206 2015/01/01 17:07:34 christos Exp $")
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
+#include "der.h"
private int match(struct magic_set *, struct magic *, uint32_t,
- const unsigned char *, size_t, size_t, int, int, int, uint16_t,
+ const unsigned char *, size_t, size_t, int, int, int, uint16_t *,
uint16_t *, int *, int *, int *);
private int mget(struct magic_set *, const unsigned char *,
- struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t,
+ struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t *,
uint16_t *, int *, int *, int *);
private int magiccheck(struct magic_set *, struct magic *);
private int32_t mprint(struct magic_set *, struct magic *);
-private int32_t moffset(struct magic_set *, struct magic *);
+private int moffset(struct magic_set *, struct magic *, size_t, int32_t *);
private void mdebug(uint32_t, const char *, size_t);
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
const unsigned char *, uint32_t, size_t, struct magic *);
private int mconvert(struct magic_set *, struct magic *, int);
private int print_sep(struct magic_set *, int);
-private int handle_annotation(struct magic_set *, struct magic *);
-private void cvt_8(union VALUETYPE *, const struct magic *);
-private void cvt_16(union VALUETYPE *, const struct magic *);
-private void cvt_32(union VALUETYPE *, const struct magic *);
-private void cvt_64(union VALUETYPE *, const struct magic *);
-
-#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
+private int handle_annotation(struct magic_set *, struct magic *, int);
+private int cvt_8(union VALUETYPE *, const struct magic *);
+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))
/*
* softmagic - lookup one file in parsed, in-memory copy of database
@@ -71,20 +89,24 @@ private void cvt_64(union VALUETYPE *, const struct magic *);
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
protected int
file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
- uint16_t indir_level, uint16_t *name_count, int mode, int text)
+ uint16_t *indir_count, uint16_t *name_count, int mode, int text)
{
struct mlist *ml;
int rv, printed_something = 0, need_separator = 0;
- uint16_t nc;
+ uint16_t nc, ic;
if (name_count == NULL) {
nc = 0;
name_count = &nc;
}
+ if (indir_count == NULL) {
+ ic = 0;
+ indir_count = &ic;
+ }
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
- text, 0, indir_level, name_count,
+ text, 0, indir_count, name_count,
&printed_something, &need_separator, NULL)) != 0)
return rv;
@@ -140,14 +162,14 @@ file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
- int flip, uint16_t indir_level, uint16_t *name_count,
+ int flip, uint16_t *indir_count, uint16_t *name_count,
int *printed_something, int *need_separator, int *returnval)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
int returnvalv = 0, e; /* if a match is found it is set to 1*/
int firstline = 1; /* a flag to print X\n X\n- X */
- int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
+ int print = (ms->flags & MAGIC_NODESC) == 0;
if (returnval == NULL)
returnval = &returnvalv;
@@ -165,11 +187,12 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
((text && (m->str_flags & FLT) == STRING_BINTEST) ||
(!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
(m->flag & mode) != mode) {
+flush:
/* Skip sub-tests */
- while (magindex + 1 < nmagic &&
- magic[magindex + 1].cont_level != 0 &&
- ++magindex)
- continue;
+ while (magindex < nmagic - 1 &&
+ magic[magindex + 1].cont_level != 0)
+ magindex++;
+ cont_level = 0;
continue; /* Skip to next top-level test*/
}
@@ -178,7 +201,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
/* if main entry matches, print it... */
switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
- flip, indir_level, name_count,
+ flip, indir_count, name_count,
printed_something, need_separator, returnval)) {
case -1:
return -1;
@@ -206,18 +229,16 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* main entry didn't match,
* flush its continuations
*/
- while (magindex < nmagic - 1 &&
- magic[magindex + 1].cont_level != 0)
- magindex++;
- continue;
+ goto flush;
}
- if ((e = handle_annotation(ms, m)) != 0) {
+ if ((e = handle_annotation(ms, m, firstline)) != 0) {
*need_separator = 1;
*printed_something = 1;
*returnval = 1;
return e;
}
+
/*
* If we are going to print something, we'll need to print
* a blank before we print something else.
@@ -233,7 +254,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
if (print && mprint(ms, m) == -1)
return -1;
- ms->c.li[cont_level].off = moffset(ms, m);
+ switch (moffset(ms, m, nbytes, &ms->c.li[cont_level].off)) {
+ case -1:
+ case 0:
+ goto flush;
+ default:
+ break;
+ }
/* and any continuations that match */
if (file_check_mem(ms, ++cont_level) == -1)
@@ -267,7 +294,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
}
#endif
switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
- text, flip, indir_level, name_count,
+ text, flip, indir_count, name_count,
printed_something, need_separator, returnval)) {
case -1:
return -1;
@@ -302,7 +329,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
} else
ms->c.li[cont_level].got_match = 1;
- if ((e = handle_annotation(ms, m)) != 0) {
+
+ if ((e = handle_annotation(ms, m, firstline)) != 0) {
*need_separator = 1;
*printed_something = 1;
*returnval = 1;
@@ -338,7 +366,16 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
if (print && mprint(ms, m) == -1)
return -1;
- ms->c.li[cont_level].off = moffset(ms, m);
+ switch (moffset(ms, m, nbytes,
+ &ms->c.li[cont_level].off)) {
+ case -1:
+ case 0:
+ flush = 1;
+ cont_level--;
+ break;
+ default:
+ break;
+ }
if (*m->desc)
*need_separator = 1;
@@ -361,6 +398,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
return *returnval; /* don't keep searching */
}
+ cont_level = 0;
}
return *returnval; /* This is hit if -k is set or there is no match */
}
@@ -518,7 +556,7 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + strlen(str);
if (*m->value.s == '\0')
- str[strcspn(str, "\n")] = '\0';
+ str[strcspn(str, "\r\n")] = '\0';
if (m->str_flags & STRING_TRIM) {
char *last;
@@ -547,7 +585,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_LEDATE:
case FILE_MEDATE:
if (file_printf(ms, F(ms, m, "%s"),
- file_fmttime(p->l + m->num_mask, FILE_T_LOCAL, tbuf)) == -1)
+ file_fmttime(p->l, 0, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint32_t);
break;
@@ -557,7 +595,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_LELDATE:
case FILE_MELDATE:
if (file_printf(ms, F(ms, m, "%s"),
- file_fmttime(p->l + m->num_mask, 0, tbuf)) == -1)
+ file_fmttime(p->l, FILE_T_LOCAL, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint32_t);
break;
@@ -566,7 +604,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQDATE:
case FILE_LEQDATE:
if (file_printf(ms, F(ms, m, "%s"),
- file_fmttime(p->q + m->num_mask, FILE_T_LOCAL, tbuf)) == -1)
+ file_fmttime(p->q, 0, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
@@ -575,7 +613,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQLDATE:
case FILE_LEQLDATE:
if (file_printf(ms, F(ms, m, "%s"),
- file_fmttime(p->q + m->num_mask, 0, tbuf)) == -1)
+ file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
@@ -584,14 +622,14 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQWDATE:
case FILE_LEQWDATE:
if (file_printf(ms, F(ms, m, "%s"),
- file_fmttime(p->q + m->num_mask, FILE_T_WINDOWS, tbuf)) == -1)
+ file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
- case FILE_FLOAT:
- case FILE_BEFLOAT:
- case FILE_LEFLOAT:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
vf = p->f;
switch (check_fmt(ms, m)) {
case -1:
@@ -609,9 +647,9 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + sizeof(float);
break;
- case FILE_DOUBLE:
- case FILE_BEDOUBLE:
- case FILE_LEDOUBLE:
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
vd = p->d;
switch (check_fmt(ms, m)) {
case -1:
@@ -629,6 +667,7 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + sizeof(double);
break;
+ case FILE_SEARCH:
case FILE_REGEX: {
char *cp;
int rval;
@@ -652,16 +691,6 @@ mprint(struct magic_set *ms, struct magic *m)
break;
}
- case FILE_SEARCH:
- if (file_printf(ms, F(ms, m, "%s"),
- file_printable(sbuf, sizeof(sbuf), m->value.s)) == -1)
- return -1;
- if ((m->str_flags & REGEX_OFFSET_START))
- t = ms->search.offset;
- else
- t = ms->search.offset + m->vallen;
- break;
-
case FILE_DEFAULT:
case FILE_CLEAR:
if (file_printf(ms, "%s", m->desc) == -1)
@@ -674,7 +703,12 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_NAME:
t = ms->offset;
break;
-
+ case FILE_DER:
+ if (file_printf(ms, F(ms, m, "%s"),
+ file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1)
+ return -1;
+ t = ms->offset;
+ break;
default:
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
return -1;
@@ -682,100 +716,152 @@ mprint(struct magic_set *ms, struct magic *m)
return (int32_t)t;
}
-private int32_t
-moffset(struct magic_set *ms, struct magic *m)
+private int
+moffset(struct magic_set *ms, struct magic *m, size_t nbytes, int32_t *op)
{
+ int32_t o;
+
switch (m->type) {
case FILE_BYTE:
- return CAST(int32_t, (ms->offset + sizeof(char)));
+ o = CAST(int32_t, (ms->offset + sizeof(char)));
+ break;
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
- return CAST(int32_t, (ms->offset + sizeof(short)));
+ o = CAST(int32_t, (ms->offset + sizeof(short)));
+ break;
case FILE_LONG:
case FILE_BELONG:
case FILE_LELONG:
case FILE_MELONG:
- return CAST(int32_t, (ms->offset + sizeof(int32_t)));
+ o = CAST(int32_t, (ms->offset + sizeof(int32_t)));
+ break;
case FILE_QUAD:
case FILE_BEQUAD:
case FILE_LEQUAD:
- return CAST(int32_t, (ms->offset + sizeof(int64_t)));
+ o = CAST(int32_t, (ms->offset + sizeof(int64_t)));
+ break;
case FILE_STRING:
case FILE_PSTRING:
case FILE_BESTRING16:
case FILE_LESTRING16:
- if (m->reln == '=' || m->reln == '!')
- return ms->offset + m->vallen;
- else {
+ if (m->reln == '=' || m->reln == '!') {
+ o = ms->offset + m->vallen;
+ } else {
union VALUETYPE *p = &ms->ms_value;
- uint32_t t;
if (*m->value.s == '\0')
- p->s[strcspn(p->s, "\n")] = '\0';
- t = CAST(uint32_t, (ms->offset + strlen(p->s)));
+ p->s[strcspn(p->s, "\r\n")] = '\0';
+ o = CAST(uint32_t, (ms->offset + strlen(p->s)));
if (m->type == FILE_PSTRING)
- t += (uint32_t)file_pstring_length_size(m);
- return t;
+ o += (uint32_t)file_pstring_length_size(m);
}
+ break;
case FILE_DATE:
case FILE_BEDATE:
case FILE_LEDATE:
case FILE_MEDATE:
- return CAST(int32_t, (ms->offset + sizeof(uint32_t)));
+ o = CAST(int32_t, (ms->offset + sizeof(uint32_t)));
+ break;
case FILE_LDATE:
case FILE_BELDATE:
case FILE_LELDATE:
case FILE_MELDATE:
- return CAST(int32_t, (ms->offset + sizeof(uint32_t)));
+ o = CAST(int32_t, (ms->offset + sizeof(uint32_t)));
+ break;
case FILE_QDATE:
case FILE_BEQDATE:
case FILE_LEQDATE:
- return CAST(int32_t, (ms->offset + sizeof(uint64_t)));
+ o = CAST(int32_t, (ms->offset + sizeof(uint64_t)));
+ break;
case FILE_QLDATE:
case FILE_BEQLDATE:
case FILE_LEQLDATE:
- return CAST(int32_t, (ms->offset + sizeof(uint64_t)));
+ o = CAST(int32_t, (ms->offset + sizeof(uint64_t)));
+ break;
case FILE_FLOAT:
case FILE_BEFLOAT:
case FILE_LEFLOAT:
- return CAST(int32_t, (ms->offset + sizeof(float)));
+ o = CAST(int32_t, (ms->offset + sizeof(float)));
+ break;
case FILE_DOUBLE:
case FILE_BEDOUBLE:
case FILE_LEDOUBLE:
- return CAST(int32_t, (ms->offset + sizeof(double)));
+ o = CAST(int32_t, (ms->offset + sizeof(double)));
+ break;
case FILE_REGEX:
if ((m->str_flags & REGEX_OFFSET_START) != 0)
- return CAST(int32_t, ms->search.offset);
+ o = CAST(int32_t, ms->search.offset);
else
- return CAST(int32_t, (ms->search.offset +
- ms->search.rm_len));
+ o = CAST(int32_t,
+ (ms->search.offset + ms->search.rm_len));
+ break;
case FILE_SEARCH:
if ((m->str_flags & REGEX_OFFSET_START) != 0)
- return CAST(int32_t, ms->search.offset);
+ o = CAST(int32_t, ms->search.offset);
else
- return CAST(int32_t, (ms->search.offset + m->vallen));
+ o = CAST(int32_t, (ms->search.offset + m->vallen));
+ break;
case FILE_CLEAR:
case FILE_DEFAULT:
case FILE_INDIRECT:
- return ms->offset;
+ o = ms->offset;
+ break;
+
+ case FILE_DER:
+ {
+ o = der_offs(ms, m, nbytes);
+ if (o == -1 || (size_t)o > nbytes) {
+ if ((ms->flags & MAGIC_DEBUG) != 0) {
+ (void)fprintf(stderr,
+ "Bad DER offset %d nbytes=%zu",
+ o, nbytes);
+ }
+ *op = 0;
+ return 0;
+ }
+ break;
+ }
default:
- return 0;
+ o = 0;
+ break;
+ }
+
+ if ((size_t)o > nbytes) {
+#if 0
+ file_error(ms, 0, "Offset out of range %zu > %zu",
+ (size_t)o, nbytes);
+#endif
+ return -1;
}
+ *op = o;
+ return 1;
+}
+
+private uint32_t
+cvt_id3(struct magic_set *ms, uint32_t v)
+{
+ v = ((((v >> 0) & 0x7f) << 0) |
+ (((v >> 8) & 0x7f) << 7) |
+ (((v >> 16) & 0x7f) << 14) |
+ (((v >> 24) & 0x7f) << 21));
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ fprintf(stderr, "id3 offs=%u\n", v);
+ return v;
}
private int
@@ -850,37 +936,45 @@ cvt_flip(int type, int flip)
p->fld *= cast m->num_mask; \
break; \
case FILE_OPDIVIDE: \
+ if (cast m->num_mask == 0) \
+ return -1; \
p->fld /= cast m->num_mask; \
break; \
case FILE_OPMODULO: \
+ if (cast m->num_mask == 0) \
+ return -1; \
p->fld %= cast m->num_mask; \
break; \
} \
if (m->mask_op & FILE_OPINVERSE) \
p->fld = ~p->fld \
-private void
+private int
cvt_8(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(b, (uint8_t));
+ return 0;
}
-private void
+private int
cvt_16(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(h, (uint16_t));
+ return 0;
}
-private void
+private int
cvt_32(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(l, (uint32_t));
+ return 0;
}
-private void
+private int
cvt_64(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(q, (uint64_t));
+ return 0;
}
#define DO_CVT2(fld, cast) \
@@ -896,20 +990,24 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
p->fld *= cast m->num_mask; \
break; \
case FILE_OPDIVIDE: \
+ if (cast m->num_mask == 0) \
+ return -1; \
p->fld /= cast m->num_mask; \
break; \
} \
-private void
+private int
cvt_float(union VALUETYPE *p, const struct magic *m)
{
DO_CVT2(f, (float));
+ return 0;
}
-private void
+private int
cvt_double(union VALUETYPE *p, const struct magic *m)
{
DO_CVT2(d, (double));
+ return 0;
}
/*
@@ -921,25 +1019,28 @@ private int
mconvert(struct magic_set *ms, struct magic *m, int flip)
{
union VALUETYPE *p = &ms->ms_value;
- uint8_t type;
- switch (type = cvt_flip(m->type, flip)) {
+ switch (cvt_flip(m->type, flip)) {
case FILE_BYTE:
- cvt_8(p, m);
+ if (cvt_8(p, m) == -1)
+ goto out;
return 1;
case FILE_SHORT:
- cvt_16(p, m);
+ if (cvt_16(p, m) == -1)
+ goto out;
return 1;
case FILE_LONG:
case FILE_DATE:
case FILE_LDATE:
- cvt_32(p, m);
+ if (cvt_32(p, m) == -1)
+ goto out;
return 1;
case FILE_QUAD:
case FILE_QDATE:
case FILE_QLDATE:
case FILE_QWDATE:
- cvt_64(p, m);
+ if (cvt_64(p, m) == -1)
+ goto out;
return 1;
case FILE_STRING:
case FILE_BESTRING16:
@@ -970,90 +1071,79 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
return 1;
}
case FILE_BESHORT:
- p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
- cvt_16(p, m);
+ p->h = (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)
- ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
- if (type == FILE_BELONG)
- cvt_32(p, m);
+ p->l = (int32_t)BE32(p);
+ if (cvt_32(p, m) == -1)
+ goto out;
return 1;
case FILE_BEQUAD:
case FILE_BEQDATE:
case FILE_BEQLDATE:
case FILE_BEQWDATE:
- 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]));
- if (type == FILE_BEQUAD)
- cvt_64(p, m);
+ p->q = (uint64_t)BE64(p);
+ if (cvt_64(p, m) == -1)
+ goto out;
return 1;
case FILE_LESHORT:
- p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
- cvt_16(p, m);
+ p->h = (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)
- ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
- if (type == FILE_LELONG)
- cvt_32(p, m);
+ p->l = (int32_t)LE32(p);
+ if (cvt_32(p, m) == -1)
+ goto out;
return 1;
case FILE_LEQUAD:
case FILE_LEQDATE:
case FILE_LEQLDATE:
case FILE_LEQWDATE:
- 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]));
- if (type == FILE_LEQUAD)
- cvt_64(p, m);
+ p->q = (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)
- ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));
- if (type == FILE_MELONG)
- cvt_32(p, m);
+ p->l = (int32_t)ME32(p);
+ if (cvt_32(p, m) == -1)
+ goto out;
return 1;
case FILE_FLOAT:
- cvt_float(p, m);
+ if (cvt_float(p, m) == -1)
+ goto out;
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);
+ p->l = BE32(p);
+ if (cvt_float(p, m) == -1)
+ goto out;
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);
+ p->l = LE32(p);
+ if (cvt_float(p, m) == -1)
+ goto out;
return 1;
case FILE_DOUBLE:
- cvt_double(p, m);
+ if (cvt_double(p, m) == -1)
+ goto out;
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);
+ p->q = BE64(p);
+ if (cvt_double(p, m) == -1)
+ goto out;
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);
+ p->q = LE64(p);
+ if (cvt_double(p, m) == -1)
+ goto out;
return 1;
case FILE_REGEX:
case FILE_SEARCH:
@@ -1061,11 +1151,15 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
case FILE_CLEAR:
case FILE_NAME:
case FILE_USE:
+ case FILE_DER:
return 1;
default:
file_magerror(ms, "invalid type %d in mconvert()", m->type);
return 0;
}
+out:
+ file_magerror(ms, "zerodivide in mconvert()");
+ return 0;
}
@@ -1088,7 +1182,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
*/
if (indir == 0) {
switch (type) {
+ case FILE_DER:
case FILE_SEARCH:
+ if (offset > nbytes)
+ offset = CAST(uint32_t, nbytes);
ms->search.s = RCAST(const char *, s) + offset;
ms->search.s_len = nbytes - offset;
ms->search.offset = offset;
@@ -1102,7 +1199,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
const char *end;
size_t lines, linecnt, bytecnt;
- if (s == NULL) {
+ if (s == NULL || nbytes < offset) {
ms->search.s_len = 0;
ms->search.s = NULL;
return 0;
@@ -1116,13 +1213,13 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
bytecnt = m->str_range;
}
- if (bytecnt == 0)
- bytecnt = 8192;
- if (bytecnt > nbytes)
- bytecnt = nbytes;
+ if (bytecnt == 0 || bytecnt > nbytes - offset)
+ bytecnt = nbytes - offset;
+ if (bytecnt > ms->regex_max)
+ bytecnt = ms->regex_max;
buf = RCAST(const char *, s) + offset;
- end = last = RCAST(const char *, s) + bytecnt;
+ end = last = RCAST(const char *, s) + bytecnt + offset;
/* mget() guarantees buf <= last */
for (lines = linecnt, b = buf; lines && b < end &&
((b = CAST(const char *,
@@ -1131,7 +1228,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
memchr(c, '\r', CAST(size_t, (end - c))))));
lines--, b++) {
last = b;
- if (b[0] == '\r' && b[1] == '\n')
+ if (b < end - 1 && b[0] == '\r' && b[1] == '\n')
b++;
}
if (lines)
@@ -1164,7 +1261,8 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
if (*dst == '\0') {
if (type == FILE_BESTRING16 ?
*(src - 1) != '\0' :
- *(src + 1) != '\0')
+ ((src + 1 < esrc) &&
+ *(src + 1) != '\0'))
*dst = ' ';
}
}
@@ -1199,23 +1297,62 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
return 0;
}
+private uint32_t
+do_ops(struct magic *m, intmax_t lhs, intmax_t off)
+{
+ intmax_t offset;
+ if (off) {
+ switch (m->in_op & FILE_OPS_MASK) {
+ case FILE_OPAND:
+ offset = lhs & off;
+ break;
+ case FILE_OPOR:
+ offset = lhs | off;
+ break;
+ case FILE_OPXOR:
+ offset = lhs ^ off;
+ break;
+ case FILE_OPADD:
+ offset = lhs + off;
+ break;
+ case FILE_OPMINUS:
+ offset = lhs - off;
+ break;
+ case FILE_OPMULTIPLY:
+ offset = lhs * off;
+ break;
+ case FILE_OPDIVIDE:
+ offset = lhs / off;
+ break;
+ case FILE_OPMODULO:
+ offset = lhs % off;
+ break;
+ }
+ } else
+ offset = lhs;
+ if (m->in_op & FILE_OPINVERSE)
+ offset = ~offset;
+
+ return (uint32_t)offset;
+}
+
private int
mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
- int flip, uint16_t indir_level, uint16_t *name_count,
+ int flip, uint16_t *indir_count, uint16_t *name_count,
int *printed_something, int *need_separator, int *returnval)
{
uint32_t offset = ms->offset;
- uint32_t lhs;
+ intmax_t lhs;
file_pushbuf_t *pb;
int rv, oneed_separator, in_type;
char *rbuf;
union VALUETYPE *p = &ms->ms_value;
struct mlist ml;
- if (indir_level >= ms->indir_max) {
- file_error(ms, 0, "indirect recursion nesting (%hu) exceeded",
- indir_level);
+ if (*indir_count >= ms->indir_max) {
+ file_error(ms, 0, "indirect count (%hu) exceeded",
+ *indir_count);
return -1;
}
@@ -1230,11 +1367,11 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
- fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%"
+ fprintf(stderr, "mget(type=%d, flag=%#x, offset=%u, o=%"
SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
"u, il=%hu, nc=%hu)\n",
m->type, m->flag, offset, o, nbytes,
- indir_level, *name_count);
+ *indir_count, *name_count);
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
#ifndef COMPILE_ONLY
file_mdump(m);
@@ -1242,347 +1379,92 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
}
if (m->flag & INDIR) {
- int off = m->in_offset;
+ intmax_t off = m->in_offset;
+ 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;
switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
- off = q->b;
+ off = SEXT(sgn,8,q->b);
break;
case FILE_SHORT:
- off = q->h;
+ off = SEXT(sgn,16,q->h);
break;
case FILE_BESHORT:
- off = (short)((q->hs[0]<<8)|(q->hs[1]));
+ off = SEXT(sgn,16,BE16(q));
break;
case FILE_LESHORT:
- off = (short)((q->hs[1]<<8)|(q->hs[0]));
+ off = SEXT(sgn,16,LE16(q));
break;
case FILE_LONG:
- off = q->l;
+ off = SEXT(sgn,32,q->l);
break;
case FILE_BELONG:
case FILE_BEID3:
- off = (int32_t)((q->hl[0]<<24)|(q->hl[1]<<16)|
- (q->hl[2]<<8)|(q->hl[3]));
+ off = SEXT(sgn,32,BE32(q));
break;
case FILE_LEID3:
case FILE_LELONG:
- off = (int32_t)((q->hl[3]<<24)|(q->hl[2]<<16)|
- (q->hl[1]<<8)|(q->hl[0]));
+ off = SEXT(sgn,32,LE32(q));
break;
case FILE_MELONG:
- off = (int32_t)((q->hl[1]<<24)|(q->hl[0]<<16)|
- (q->hl[3]<<8)|(q->hl[2]));
+ off = SEXT(sgn,32,ME32(q));
break;
}
if ((ms->flags & MAGIC_DEBUG) != 0)
- fprintf(stderr, "indirect offs=%u\n", off);
+ fprintf(stderr, "indirect offs=%jd\n", off);
}
switch (in_type = cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
if (OFFSET_OOB(nbytes, offset, 1))
return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = p->b & off;
- break;
- case FILE_OPOR:
- offset = p->b | off;
- break;
- case FILE_OPXOR:
- offset = p->b ^ off;
- break;
- case FILE_OPADD:
- offset = p->b + off;
- break;
- case FILE_OPMINUS:
- offset = p->b - off;
- break;
- case FILE_OPMULTIPLY:
- offset = p->b * off;
- break;
- case FILE_OPDIVIDE:
- offset = p->b / off;
- break;
- case FILE_OPMODULO:
- offset = p->b % off;
- break;
- }
- } else
- offset = p->b;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ offset = do_ops(m, SEXT(sgn,8,p->b), off);
break;
case FILE_BESHORT:
if (OFFSET_OOB(nbytes, offset, 2))
return 0;
- lhs = (p->hs[0] << 8) | p->hs[1];
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = lhs & off;
- break;
- case FILE_OPOR:
- offset = lhs | off;
- break;
- case FILE_OPXOR:
- offset = lhs ^ off;
- break;
- case FILE_OPADD:
- offset = lhs + off;
- break;
- case FILE_OPMINUS:
- offset = lhs - off;
- break;
- case FILE_OPMULTIPLY:
- offset = lhs * off;
- break;
- case FILE_OPDIVIDE:
- offset = lhs / off;
- break;
- case FILE_OPMODULO:
- offset = lhs % off;
- break;
- }
- } else
- offset = lhs;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ offset = do_ops(m, SEXT(sgn,16,BE16(p)), off);
break;
case FILE_LESHORT:
if (OFFSET_OOB(nbytes, offset, 2))
return 0;
- lhs = (p->hs[1] << 8) | p->hs[0];
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = lhs & off;
- break;
- case FILE_OPOR:
- offset = lhs | off;
- break;
- case FILE_OPXOR:
- offset = lhs ^ off;
- break;
- case FILE_OPADD:
- offset = lhs + off;
- break;
- case FILE_OPMINUS:
- offset = lhs - off;
- break;
- case FILE_OPMULTIPLY:
- offset = lhs * off;
- break;
- case FILE_OPDIVIDE:
- offset = lhs / off;
- break;
- case FILE_OPMODULO:
- offset = lhs % off;
- break;
- }
- } else
- offset = lhs;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ offset = do_ops(m, SEXT(sgn,16,LE16(p)), off);
break;
case FILE_SHORT:
if (OFFSET_OOB(nbytes, offset, 2))
return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = p->h & off;
- break;
- case FILE_OPOR:
- offset = p->h | off;
- break;
- case FILE_OPXOR:
- offset = p->h ^ off;
- break;
- case FILE_OPADD:
- offset = p->h + off;
- break;
- case FILE_OPMINUS:
- offset = p->h - off;
- break;
- case FILE_OPMULTIPLY:
- offset = p->h * off;
- break;
- case FILE_OPDIVIDE:
- offset = p->h / off;
- break;
- case FILE_OPMODULO:
- offset = p->h % off;
- break;
- }
- }
- else
- offset = p->h;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ offset = do_ops(m, SEXT(sgn,16,p->h), off);
break;
case FILE_BELONG:
case FILE_BEID3:
if (OFFSET_OOB(nbytes, offset, 4))
return 0;
- lhs = (p->hl[0] << 24) | (p->hl[1] << 16) |
- (p->hl[2] << 8) | p->hl[3];
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = lhs & off;
- break;
- case FILE_OPOR:
- offset = lhs | off;
- break;
- case FILE_OPXOR:
- offset = lhs ^ off;
- break;
- case FILE_OPADD:
- offset = lhs + off;
- break;
- case FILE_OPMINUS:
- offset = lhs - off;
- break;
- case FILE_OPMULTIPLY:
- offset = lhs * off;
- break;
- case FILE_OPDIVIDE:
- offset = lhs / off;
- break;
- case FILE_OPMODULO:
- offset = lhs % off;
- break;
- }
- } else
- offset = lhs;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ lhs = BE32(p);
+ if (in_type == FILE_BEID3)
+ lhs = cvt_id3(ms, (uint32_t)lhs);
+ offset = do_ops(m, SEXT(sgn,32,lhs), off);
break;
case FILE_LELONG:
case FILE_LEID3:
if (OFFSET_OOB(nbytes, offset, 4))
return 0;
- lhs = (p->hl[3] << 24) | (p->hl[2] << 16) |
- (p->hl[1] << 8) | p->hl[0];
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = lhs & off;
- break;
- case FILE_OPOR:
- offset = lhs | off;
- break;
- case FILE_OPXOR:
- offset = lhs ^ off;
- break;
- case FILE_OPADD:
- offset = lhs + off;
- break;
- case FILE_OPMINUS:
- offset = lhs - off;
- break;
- case FILE_OPMULTIPLY:
- offset = lhs * off;
- break;
- case FILE_OPDIVIDE:
- offset = lhs / off;
- break;
- case FILE_OPMODULO:
- offset = lhs % off;
- break;
- }
- } else
- offset = lhs;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ lhs = LE32(p);
+ if (in_type == FILE_LEID3)
+ lhs = cvt_id3(ms, (uint32_t)lhs);
+ offset = do_ops(m, SEXT(sgn,32,lhs), off);
break;
case FILE_MELONG:
if (OFFSET_OOB(nbytes, offset, 4))
return 0;
- lhs = (p->hl[1] << 24) | (p->hl[0] << 16) |
- (p->hl[3] << 8) | p->hl[2];
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = lhs & off;
- break;
- case FILE_OPOR:
- offset = lhs | off;
- break;
- case FILE_OPXOR:
- offset = lhs ^ off;
- break;
- case FILE_OPADD:
- offset = lhs + off;
- break;
- case FILE_OPMINUS:
- offset = lhs - off;
- break;
- case FILE_OPMULTIPLY:
- offset = lhs * off;
- break;
- case FILE_OPDIVIDE:
- offset = lhs / off;
- break;
- case FILE_OPMODULO:
- offset = lhs % off;
- break;
- }
- } else
- offset = lhs;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
+ offset = do_ops(m, SEXT(sgn,32,ME32(p)), off);
break;
case FILE_LONG:
if (OFFSET_OOB(nbytes, offset, 4))
return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = p->l & off;
- break;
- case FILE_OPOR:
- offset = p->l | off;
- break;
- case FILE_OPXOR:
- offset = p->l ^ off;
- break;
- case FILE_OPADD:
- offset = p->l + off;
- break;
- case FILE_OPMINUS:
- offset = p->l - off;
- break;
- case FILE_OPMULTIPLY:
- offset = p->l * off;
- break;
- case FILE_OPDIVIDE:
- offset = p->l / off;
- break;
- case FILE_OPMODULO:
- offset = p->l % off;
- break;
- }
- } else
- offset = p->l;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- default:
- break;
- }
-
- switch (in_type) {
- case FILE_LEID3:
- case FILE_BEID3:
- offset = ((((offset >> 0) & 0x7f) << 0) |
- (((offset >> 8) & 0x7f) << 7) |
- (((offset >> 16) & 0x7f) << 14) |
- (((offset >> 24) & 0x7f) << 21)) + 10;
+ offset = do_ops(m, SEXT(sgn,32,p->l), off);
break;
default:
break;
@@ -1666,7 +1548,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
case FILE_INDIRECT:
if (m->str_flags & INDIRECT_RELATIVE)
- offset += o;
+ offset += CAST(uint32_t, o);
if (offset == 0)
return 0;
@@ -1676,8 +1558,9 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
if ((pb = file_push_buffer(ms)) == NULL)
return -1;
+ (*indir_count)++;
rv = file_softmagic(ms, s + offset, nbytes - offset,
- indir_level + 1, name_count, BINTEST, text);
+ indir_count, name_count, BINTEST, text);
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
@@ -1687,7 +1570,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
return -1;
if (rv == 1) {
- if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
+ if ((ms->flags & MAGIC_NODESC) == 0 &&
file_printf(ms, F(ms, m, "%u"), offset) == -1) {
free(rbuf);
return -1;
@@ -1717,16 +1600,19 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
if (m->flag & NOSPACE)
*need_separator = 0;
rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
- mode, text, flip, indir_level, name_count,
+ mode, text, flip, indir_count, name_count,
printed_something, need_separator, returnval);
if (rv != 1)
*need_separator = oneed_separator;
- return rv;
+ return 1;
case FILE_NAME:
+ if (ms->flags & MAGIC_NODESC)
+ return 1;
if (file_printf(ms, "%s", m->desc) == -1)
return -1;
return 1;
+ case FILE_DER:
case FILE_DEFAULT: /* nothing to check */
case FILE_CLEAR:
default:
@@ -1748,6 +1634,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
*/
const unsigned char *a = (const unsigned char *)s1;
const unsigned char *b = (const unsigned char *)s2;
+ const unsigned char *eb = b + len;
uint64_t v;
/*
@@ -1762,6 +1649,10 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
}
else { /* combine the others */
while (len-- > 0) {
+ if (b >= eb) {
+ v = 1;
+ break;
+ }
if ((flags & STRING_IGNORE_LOWERCASE) &&
islower(*a)) {
if ((v = tolower(*b++) - *a++) != '\0')
@@ -1777,7 +1668,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
a++;
if (isspace(*b++)) {
if (!isspace(*a))
- while (isspace(*b))
+ while (b < eb && isspace(*b))
b++;
}
else {
@@ -1788,7 +1679,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
isspace(*a)) {
a++;
- while (isspace(*b))
+ while (b < eb && isspace(*b))
b++;
}
else {
@@ -1959,12 +1850,13 @@ magiccheck(struct magic_set *ms, struct magic *m)
for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
if (slen + idx > ms->search.s_len)
- break;
+ return 0;
v = file_strncmp(m->value.s, ms->search.s + idx, slen,
m->str_flags);
if (v == 0) { /* found match */
ms->search.offset += idx;
+ ms->search.rm_len = ms->search.s_len - idx;
break;
}
}
@@ -1986,14 +1878,13 @@ magiccheck(struct magic_set *ms, struct magic *m)
file_regerror(&rx, rc, ms);
v = (uint64_t)-1;
} else {
- regmatch_t pmatch[1];
+ regmatch_t pmatch;
size_t slen = ms->search.s_len;
-#ifndef REG_STARTEND
-#define REG_STARTEND 0
char *copy;
if (slen != 0) {
- copy = malloc(slen);
+ copy = CAST(char *, malloc(slen));
if (copy == NULL) {
+ file_regfree(&rx);
file_error(ms, errno,
"can't allocate %" SIZE_T_FORMAT "u bytes",
slen);
@@ -2003,25 +1894,18 @@ magiccheck(struct magic_set *ms, struct magic *m)
copy[--slen] = '\0';
search = copy;
} else {
- search = ms->search.s;
+ search = CCAST(char *, "");
copy = NULL;
}
-#else
- search = ms->search.s;
- pmatch[0].rm_so = 0;
- pmatch[0].rm_eo = slen;
-#endif
rc = file_regexec(&rx, (const char *)search,
- 1, pmatch, REG_STARTEND);
-#if REG_STARTEND == 0
+ 1, &pmatch, 0);
free(copy);
-#endif
switch (rc) {
case 0:
- ms->search.s += (int)pmatch[0].rm_so;
- ms->search.offset += (size_t)pmatch[0].rm_so;
+ ms->search.s += (int)pmatch.rm_so;
+ ms->search.offset += (size_t)pmatch.rm_so;
ms->search.rm_len =
- (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
+ (size_t)(pmatch.rm_eo - pmatch.rm_so);
v = 0;
break;
@@ -2044,6 +1928,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_USE:
case FILE_NAME:
return 1;
+ case FILE_DER:
+ matched = der_cmp(ms, m);
+ if (matched == -1) {
+ if ((ms->flags & MAGIC_DEBUG) != 0) {
+ (void) fprintf(stderr,
+ "EOF comparing DER entries");
+ }
+ return 0;
+ }
+ return matched;
default:
file_magerror(ms, "invalid type %d in magiccheck()", m->type);
return -1;
@@ -2141,14 +2035,25 @@ magiccheck(struct magic_set *ms, struct magic *m)
}
private int
-handle_annotation(struct magic_set *ms, struct magic *m)
+handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
{
- if (ms->flags & MAGIC_APPLE) {
+ if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
+ if (!firstline && file_printf(ms, "\n- ") == -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)
+ return -1;
+ if (file_printf(ms, "%s", m->ext) == -1)
+ return -1;
+ return 1;
+ }
if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
+ if (!firstline && file_printf(ms, "\n- ") == -1)
+ return -1;
if (file_printf(ms, "%s", m->mimetype) == -1)
return -1;
return 1;
@@ -2159,8 +2064,8 @@ handle_annotation(struct magic_set *ms, struct magic *m)
private int
print_sep(struct magic_set *ms, int firstline)
{
- if (ms->flags & MAGIC_MIME)
- return 0;
+// if (ms->flags & MAGIC_NODESC)
+// return 0;
if (firstline)
return 0;
/*