|
@@ -32,7 +32,7 @@
|
|
#include "file.h"
|
|
#include "file.h"
|
|
|
|
|
|
#ifndef lint
|
|
#ifndef lint
|
|
-FILE_RCSID("@(#)$File: softmagic.c,v 1.218 2015/09/11 17:24:09 christos Exp $")
|
|
|
|
|
|
+FILE_RCSID("@(#)$File: softmagic.c,v 1.234 2016/06/13 12:02:06 christos Exp $")
|
|
#endif /* lint */
|
|
#endif /* lint */
|
|
|
|
|
|
#include "magic.h"
|
|
#include "magic.h"
|
|
@@ -41,26 +41,27 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.218 2015/09/11 17:24:09 christos Exp $")
|
|
#include <ctype.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <time.h>
|
|
|
|
+#include "der.h"
|
|
|
|
|
|
private int match(struct magic_set *, struct magic *, uint32_t,
|
|
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 *);
|
|
uint16_t *, int *, int *, int *);
|
|
private int mget(struct magic_set *, const unsigned char *,
|
|
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 *);
|
|
uint16_t *, int *, int *, int *);
|
|
private int magiccheck(struct magic_set *, struct magic *);
|
|
private int magiccheck(struct magic_set *, struct magic *);
|
|
private int32_t mprint(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 void mdebug(uint32_t, const char *, size_t);
|
|
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
|
|
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
|
|
const unsigned char *, uint32_t, size_t, struct magic *);
|
|
const unsigned char *, uint32_t, size_t, struct magic *);
|
|
private int mconvert(struct magic_set *, struct magic *, int);
|
|
private int mconvert(struct magic_set *, struct magic *, int);
|
|
private int print_sep(struct magic_set *, int);
|
|
private int print_sep(struct magic_set *, int);
|
|
private int handle_annotation(struct magic_set *, struct magic *);
|
|
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 *);
|
|
|
|
|
|
+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) < (o) || (i) > ((n) - (o)))
|
|
#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
|
|
#define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
|
|
#define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
|
|
@@ -87,20 +88,24 @@ private void cvt_64(union VALUETYPE *, const struct magic *);
|
|
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
|
|
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
|
|
protected int
|
|
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,
|
|
- 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;
|
|
struct mlist *ml;
|
|
int rv, printed_something = 0, need_separator = 0;
|
|
int rv, printed_something = 0, need_separator = 0;
|
|
- uint16_t nc;
|
|
|
|
|
|
+ uint16_t nc, ic;
|
|
|
|
|
|
if (name_count == NULL) {
|
|
if (name_count == NULL) {
|
|
nc = 0;
|
|
nc = 0;
|
|
name_count = &nc;
|
|
name_count = &nc;
|
|
}
|
|
}
|
|
|
|
+ if (indir_count == NULL) {
|
|
|
|
+ ic = 0;
|
|
|
|
+ indir_count = ⁣
|
|
|
|
+ }
|
|
|
|
|
|
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
|
|
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,
|
|
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)
|
|
&printed_something, &need_separator, NULL)) != 0)
|
|
return rv;
|
|
return rv;
|
|
|
|
|
|
@@ -156,7 +161,7 @@ file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
|
|
private int
|
|
private int
|
|
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
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,
|
|
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)
|
|
int *printed_something, int *need_separator, int *returnval)
|
|
{
|
|
{
|
|
uint32_t magindex = 0;
|
|
uint32_t magindex = 0;
|
|
@@ -181,11 +186,11 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
((text && (m->str_flags & FLT) == STRING_BINTEST) ||
|
|
((text && (m->str_flags & FLT) == STRING_BINTEST) ||
|
|
(!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
|
|
(!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
|
|
(m->flag & mode) != mode) {
|
|
(m->flag & mode) != mode) {
|
|
|
|
+flush:
|
|
/* Skip sub-tests */
|
|
/* 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++;
|
|
continue; /* Skip to next top-level test*/
|
|
continue; /* Skip to next top-level test*/
|
|
}
|
|
}
|
|
|
|
|
|
@@ -194,7 +199,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
|
|
|
|
/* if main entry matches, print it... */
|
|
/* if main entry matches, print it... */
|
|
switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
|
|
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)) {
|
|
printed_something, need_separator, returnval)) {
|
|
case -1:
|
|
case -1:
|
|
return -1;
|
|
return -1;
|
|
@@ -222,10 +227,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
* main entry didn't match,
|
|
* main entry didn't match,
|
|
* flush its continuations
|
|
* 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)) != 0) {
|
|
@@ -234,6 +236,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
*returnval = 1;
|
|
*returnval = 1;
|
|
return e;
|
|
return e;
|
|
}
|
|
}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* If we are going to print something, we'll need to print
|
|
* If we are going to print something, we'll need to print
|
|
* a blank before we print something else.
|
|
* a blank before we print something else.
|
|
@@ -249,7 +252,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
if (print && mprint(ms, m) == -1)
|
|
if (print && mprint(ms, m) == -1)
|
|
return -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 */
|
|
/* and any continuations that match */
|
|
if (file_check_mem(ms, ++cont_level) == -1)
|
|
if (file_check_mem(ms, ++cont_level) == -1)
|
|
@@ -283,7 +292,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
|
|
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)) {
|
|
printed_something, need_separator, returnval)) {
|
|
case -1:
|
|
case -1:
|
|
return -1;
|
|
return -1;
|
|
@@ -318,6 +327,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
break;
|
|
break;
|
|
} else
|
|
} else
|
|
ms->c.li[cont_level].got_match = 1;
|
|
ms->c.li[cont_level].got_match = 1;
|
|
|
|
+
|
|
if ((e = handle_annotation(ms, m)) != 0) {
|
|
if ((e = handle_annotation(ms, m)) != 0) {
|
|
*need_separator = 1;
|
|
*need_separator = 1;
|
|
*printed_something = 1;
|
|
*printed_something = 1;
|
|
@@ -354,7 +364,15 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
if (print && mprint(ms, m) == -1)
|
|
if (print && mprint(ms, m) == -1)
|
|
return -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;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
if (*m->desc)
|
|
if (*m->desc)
|
|
*need_separator = 1;
|
|
*need_separator = 1;
|
|
@@ -682,7 +700,12 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
case FILE_NAME:
|
|
case FILE_NAME:
|
|
t = ms->offset;
|
|
t = ms->offset;
|
|
break;
|
|
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:
|
|
default:
|
|
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
|
|
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
|
|
return -1;
|
|
return -1;
|
|
@@ -690,100 +713,152 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
return (int32_t)t;
|
|
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) {
|
|
switch (m->type) {
|
|
case FILE_BYTE:
|
|
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_SHORT:
|
|
case FILE_BESHORT:
|
|
case FILE_BESHORT:
|
|
case FILE_LESHORT:
|
|
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_LONG:
|
|
case FILE_BELONG:
|
|
case FILE_BELONG:
|
|
case FILE_LELONG:
|
|
case FILE_LELONG:
|
|
case FILE_MELONG:
|
|
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_QUAD:
|
|
case FILE_BEQUAD:
|
|
case FILE_BEQUAD:
|
|
case FILE_LEQUAD:
|
|
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_STRING:
|
|
case FILE_PSTRING:
|
|
case FILE_PSTRING:
|
|
case FILE_BESTRING16:
|
|
case FILE_BESTRING16:
|
|
case FILE_LESTRING16:
|
|
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;
|
|
union VALUETYPE *p = &ms->ms_value;
|
|
- uint32_t t;
|
|
|
|
|
|
|
|
if (*m->value.s == '\0')
|
|
if (*m->value.s == '\0')
|
|
p->s[strcspn(p->s, "\r\n")] = '\0';
|
|
p->s[strcspn(p->s, "\r\n")] = '\0';
|
|
- t = CAST(uint32_t, (ms->offset + strlen(p->s)));
|
|
|
|
|
|
+ o = CAST(uint32_t, (ms->offset + strlen(p->s)));
|
|
if (m->type == FILE_PSTRING)
|
|
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_DATE:
|
|
case FILE_BEDATE:
|
|
case FILE_BEDATE:
|
|
case FILE_LEDATE:
|
|
case FILE_LEDATE:
|
|
case FILE_MEDATE:
|
|
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_LDATE:
|
|
case FILE_BELDATE:
|
|
case FILE_BELDATE:
|
|
case FILE_LELDATE:
|
|
case FILE_LELDATE:
|
|
case FILE_MELDATE:
|
|
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_QDATE:
|
|
case FILE_BEQDATE:
|
|
case FILE_BEQDATE:
|
|
case FILE_LEQDATE:
|
|
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_QLDATE:
|
|
case FILE_BEQLDATE:
|
|
case FILE_BEQLDATE:
|
|
case FILE_LEQLDATE:
|
|
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_FLOAT:
|
|
case FILE_BEFLOAT:
|
|
case FILE_BEFLOAT:
|
|
case FILE_LEFLOAT:
|
|
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_DOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
- return CAST(int32_t, (ms->offset + sizeof(double)));
|
|
|
|
|
|
+ o = CAST(int32_t, (ms->offset + sizeof(double)));
|
|
|
|
+ break;
|
|
|
|
|
|
case FILE_REGEX:
|
|
case FILE_REGEX:
|
|
if ((m->str_flags & REGEX_OFFSET_START) != 0)
|
|
if ((m->str_flags & REGEX_OFFSET_START) != 0)
|
|
- return CAST(int32_t, ms->search.offset);
|
|
|
|
|
|
+ o = CAST(int32_t, ms->search.offset);
|
|
else
|
|
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:
|
|
case FILE_SEARCH:
|
|
if ((m->str_flags & REGEX_OFFSET_START) != 0)
|
|
if ((m->str_flags & REGEX_OFFSET_START) != 0)
|
|
- return CAST(int32_t, ms->search.offset);
|
|
|
|
|
|
+ o = CAST(int32_t, ms->search.offset);
|
|
else
|
|
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_CLEAR:
|
|
case FILE_DEFAULT:
|
|
case FILE_DEFAULT:
|
|
case FILE_INDIRECT:
|
|
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:
|
|
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
|
|
private int
|
|
@@ -858,37 +933,45 @@ cvt_flip(int type, int flip)
|
|
p->fld *= cast m->num_mask; \
|
|
p->fld *= cast m->num_mask; \
|
|
break; \
|
|
break; \
|
|
case FILE_OPDIVIDE: \
|
|
case FILE_OPDIVIDE: \
|
|
|
|
+ if (cast m->num_mask == 0) \
|
|
|
|
+ return -1; \
|
|
p->fld /= cast m->num_mask; \
|
|
p->fld /= cast m->num_mask; \
|
|
break; \
|
|
break; \
|
|
case FILE_OPMODULO: \
|
|
case FILE_OPMODULO: \
|
|
|
|
+ if (cast m->num_mask == 0) \
|
|
|
|
+ return -1; \
|
|
p->fld %= cast m->num_mask; \
|
|
p->fld %= cast m->num_mask; \
|
|
break; \
|
|
break; \
|
|
} \
|
|
} \
|
|
if (m->mask_op & FILE_OPINVERSE) \
|
|
if (m->mask_op & FILE_OPINVERSE) \
|
|
p->fld = ~p->fld \
|
|
p->fld = ~p->fld \
|
|
|
|
|
|
-private void
|
|
|
|
|
|
+private int
|
|
cvt_8(union VALUETYPE *p, const struct magic *m)
|
|
cvt_8(union VALUETYPE *p, const struct magic *m)
|
|
{
|
|
{
|
|
DO_CVT(b, (uint8_t));
|
|
DO_CVT(b, (uint8_t));
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-private void
|
|
|
|
|
|
+private int
|
|
cvt_16(union VALUETYPE *p, const struct magic *m)
|
|
cvt_16(union VALUETYPE *p, const struct magic *m)
|
|
{
|
|
{
|
|
DO_CVT(h, (uint16_t));
|
|
DO_CVT(h, (uint16_t));
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-private void
|
|
|
|
|
|
+private int
|
|
cvt_32(union VALUETYPE *p, const struct magic *m)
|
|
cvt_32(union VALUETYPE *p, const struct magic *m)
|
|
{
|
|
{
|
|
DO_CVT(l, (uint32_t));
|
|
DO_CVT(l, (uint32_t));
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-private void
|
|
|
|
|
|
+private int
|
|
cvt_64(union VALUETYPE *p, const struct magic *m)
|
|
cvt_64(union VALUETYPE *p, const struct magic *m)
|
|
{
|
|
{
|
|
DO_CVT(q, (uint64_t));
|
|
DO_CVT(q, (uint64_t));
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
#define DO_CVT2(fld, cast) \
|
|
#define DO_CVT2(fld, cast) \
|
|
@@ -904,20 +987,24 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
|
|
p->fld *= cast m->num_mask; \
|
|
p->fld *= cast m->num_mask; \
|
|
break; \
|
|
break; \
|
|
case FILE_OPDIVIDE: \
|
|
case FILE_OPDIVIDE: \
|
|
|
|
+ if (cast m->num_mask == 0) \
|
|
|
|
+ return -1; \
|
|
p->fld /= cast m->num_mask; \
|
|
p->fld /= cast m->num_mask; \
|
|
break; \
|
|
break; \
|
|
} \
|
|
} \
|
|
|
|
|
|
-private void
|
|
|
|
|
|
+private int
|
|
cvt_float(union VALUETYPE *p, const struct magic *m)
|
|
cvt_float(union VALUETYPE *p, const struct magic *m)
|
|
{
|
|
{
|
|
DO_CVT2(f, (float));
|
|
DO_CVT2(f, (float));
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-private void
|
|
|
|
|
|
+private int
|
|
cvt_double(union VALUETYPE *p, const struct magic *m)
|
|
cvt_double(union VALUETYPE *p, const struct magic *m)
|
|
{
|
|
{
|
|
DO_CVT2(d, (double));
|
|
DO_CVT2(d, (double));
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -933,21 +1020,25 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
|
|
|
|
|
|
switch (type = cvt_flip(m->type, flip)) {
|
|
switch (type = cvt_flip(m->type, flip)) {
|
|
case FILE_BYTE:
|
|
case FILE_BYTE:
|
|
- cvt_8(p, m);
|
|
|
|
|
|
+ if (cvt_8(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_SHORT:
|
|
case FILE_SHORT:
|
|
- cvt_16(p, m);
|
|
|
|
|
|
+ if (cvt_16(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_LONG:
|
|
case FILE_LONG:
|
|
case FILE_DATE:
|
|
case FILE_DATE:
|
|
case FILE_LDATE:
|
|
case FILE_LDATE:
|
|
- cvt_32(p, m);
|
|
|
|
|
|
+ if (cvt_32(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_QUAD:
|
|
case FILE_QUAD:
|
|
case FILE_QDATE:
|
|
case FILE_QDATE:
|
|
case FILE_QLDATE:
|
|
case FILE_QLDATE:
|
|
case FILE_QWDATE:
|
|
case FILE_QWDATE:
|
|
- cvt_64(p, m);
|
|
|
|
|
|
+ if (cvt_64(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_STRING:
|
|
case FILE_STRING:
|
|
case FILE_BESTRING16:
|
|
case FILE_BESTRING16:
|
|
@@ -979,65 +1070,78 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
|
|
}
|
|
}
|
|
case FILE_BESHORT:
|
|
case FILE_BESHORT:
|
|
p->h = (short)BE16(p);
|
|
p->h = (short)BE16(p);
|
|
- cvt_16(p, m);
|
|
|
|
|
|
+ if (cvt_16(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_BELONG:
|
|
case FILE_BELONG:
|
|
case FILE_BEDATE:
|
|
case FILE_BEDATE:
|
|
case FILE_BELDATE:
|
|
case FILE_BELDATE:
|
|
p->l = (int32_t)BE32(p);
|
|
p->l = (int32_t)BE32(p);
|
|
- cvt_32(p, m);
|
|
|
|
|
|
+ if (cvt_32(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_BEQUAD:
|
|
case FILE_BEQUAD:
|
|
case FILE_BEQDATE:
|
|
case FILE_BEQDATE:
|
|
case FILE_BEQLDATE:
|
|
case FILE_BEQLDATE:
|
|
case FILE_BEQWDATE:
|
|
case FILE_BEQWDATE:
|
|
p->q = (uint64_t)BE64(p);
|
|
p->q = (uint64_t)BE64(p);
|
|
- cvt_64(p, m);
|
|
|
|
|
|
+ if (cvt_64(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_LESHORT:
|
|
case FILE_LESHORT:
|
|
p->h = (short)LE16(p);
|
|
p->h = (short)LE16(p);
|
|
- cvt_16(p, m);
|
|
|
|
|
|
+ if (cvt_16(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_LELONG:
|
|
case FILE_LELONG:
|
|
case FILE_LEDATE:
|
|
case FILE_LEDATE:
|
|
case FILE_LELDATE:
|
|
case FILE_LELDATE:
|
|
p->l = (int32_t)LE32(p);
|
|
p->l = (int32_t)LE32(p);
|
|
- cvt_32(p, m);
|
|
|
|
|
|
+ if (cvt_32(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_LEQUAD:
|
|
case FILE_LEQUAD:
|
|
case FILE_LEQDATE:
|
|
case FILE_LEQDATE:
|
|
case FILE_LEQLDATE:
|
|
case FILE_LEQLDATE:
|
|
case FILE_LEQWDATE:
|
|
case FILE_LEQWDATE:
|
|
p->q = (uint64_t)LE64(p);
|
|
p->q = (uint64_t)LE64(p);
|
|
- cvt_64(p, m);
|
|
|
|
|
|
+ if (cvt_64(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_MELONG:
|
|
case FILE_MELONG:
|
|
case FILE_MEDATE:
|
|
case FILE_MEDATE:
|
|
case FILE_MELDATE:
|
|
case FILE_MELDATE:
|
|
p->l = (int32_t)ME32(p);
|
|
p->l = (int32_t)ME32(p);
|
|
- cvt_32(p, m);
|
|
|
|
|
|
+ if (cvt_32(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_FLOAT:
|
|
case FILE_FLOAT:
|
|
- cvt_float(p, m);
|
|
|
|
|
|
+ if (cvt_float(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_BEFLOAT:
|
|
case FILE_BEFLOAT:
|
|
p->l = BE32(p);
|
|
p->l = BE32(p);
|
|
- cvt_float(p, m);
|
|
|
|
|
|
+ if (cvt_float(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_LEFLOAT:
|
|
case FILE_LEFLOAT:
|
|
p->l = LE32(p);
|
|
p->l = LE32(p);
|
|
- cvt_float(p, m);
|
|
|
|
|
|
+ if (cvt_float(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_DOUBLE:
|
|
case FILE_DOUBLE:
|
|
- cvt_double(p, m);
|
|
|
|
|
|
+ if (cvt_double(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_BEDOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
p->q = BE64(p);
|
|
p->q = BE64(p);
|
|
- cvt_double(p, m);
|
|
|
|
|
|
+ if (cvt_double(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_LEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
p->q = LE64(p);
|
|
p->q = LE64(p);
|
|
- cvt_double(p, m);
|
|
|
|
|
|
+ if (cvt_double(p, m) == -1)
|
|
|
|
+ goto out;
|
|
return 1;
|
|
return 1;
|
|
case FILE_REGEX:
|
|
case FILE_REGEX:
|
|
case FILE_SEARCH:
|
|
case FILE_SEARCH:
|
|
@@ -1045,11 +1149,15 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
|
|
case FILE_CLEAR:
|
|
case FILE_CLEAR:
|
|
case FILE_NAME:
|
|
case FILE_NAME:
|
|
case FILE_USE:
|
|
case FILE_USE:
|
|
|
|
+ case FILE_DER:
|
|
return 1;
|
|
return 1;
|
|
default:
|
|
default:
|
|
file_magerror(ms, "invalid type %d in mconvert()", m->type);
|
|
file_magerror(ms, "invalid type %d in mconvert()", m->type);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+out:
|
|
|
|
+ file_magerror(ms, "zerodivide in mconvert()");
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1072,7 +1180,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
*/
|
|
*/
|
|
if (indir == 0) {
|
|
if (indir == 0) {
|
|
switch (type) {
|
|
switch (type) {
|
|
|
|
+ case FILE_DER:
|
|
case FILE_SEARCH:
|
|
case FILE_SEARCH:
|
|
|
|
+ if (offset > nbytes)
|
|
|
|
+ offset = nbytes;
|
|
ms->search.s = RCAST(const char *, s) + offset;
|
|
ms->search.s = RCAST(const char *, s) + offset;
|
|
ms->search.s_len = nbytes - offset;
|
|
ms->search.s_len = nbytes - offset;
|
|
ms->search.offset = offset;
|
|
ms->search.offset = offset;
|
|
@@ -1186,7 +1297,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
private int
|
|
private int
|
|
mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
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,
|
|
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)
|
|
int *printed_something, int *need_separator, int *returnval)
|
|
{
|
|
{
|
|
uint32_t offset = ms->offset;
|
|
uint32_t offset = ms->offset;
|
|
@@ -1197,9 +1308,9 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
union VALUETYPE *p = &ms->ms_value;
|
|
union VALUETYPE *p = &ms->ms_value;
|
|
struct mlist ml;
|
|
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;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1218,7 +1329,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
|
|
SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
|
|
"u, il=%hu, nc=%hu)\n",
|
|
"u, il=%hu, nc=%hu)\n",
|
|
m->type, m->flag, offset, o, nbytes,
|
|
m->type, m->flag, offset, o, nbytes,
|
|
- indir_level, *name_count);
|
|
|
|
|
|
+ *indir_count, *name_count);
|
|
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
|
|
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
|
|
#ifndef COMPILE_ONLY
|
|
#ifndef COMPILE_ONLY
|
|
file_mdump(m);
|
|
file_mdump(m);
|
|
@@ -1230,6 +1341,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
if (m->in_op & FILE_OPINDIRECT) {
|
|
if (m->in_op & FILE_OPINDIRECT) {
|
|
const union VALUETYPE *q = CAST(const union VALUETYPE *,
|
|
const union VALUETYPE *q = CAST(const union VALUETYPE *,
|
|
((const void *)(s + offset + off)));
|
|
((const void *)(s + offset + off)));
|
|
|
|
+ if (OFFSET_OOB(nbytes, offset + off, sizeof(*q)))
|
|
|
|
+ return 0;
|
|
switch (cvt_flip(m->in_type, flip)) {
|
|
switch (cvt_flip(m->in_type, flip)) {
|
|
case FILE_BYTE:
|
|
case FILE_BYTE:
|
|
off = q->b;
|
|
off = q->b;
|
|
@@ -1410,6 +1523,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
if (OFFSET_OOB(nbytes, offset, 4))
|
|
if (OFFSET_OOB(nbytes, offset, 4))
|
|
return 0;
|
|
return 0;
|
|
lhs = BE32(p);
|
|
lhs = BE32(p);
|
|
|
|
+ if (in_type == FILE_BEID3)
|
|
|
|
+ lhs = cvt_id3(ms, lhs);
|
|
if (off) {
|
|
if (off) {
|
|
switch (m->in_op & FILE_OPS_MASK) {
|
|
switch (m->in_op & FILE_OPS_MASK) {
|
|
case FILE_OPAND:
|
|
case FILE_OPAND:
|
|
@@ -1447,6 +1562,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
if (OFFSET_OOB(nbytes, offset, 4))
|
|
if (OFFSET_OOB(nbytes, offset, 4))
|
|
return 0;
|
|
return 0;
|
|
lhs = LE32(p);
|
|
lhs = LE32(p);
|
|
|
|
+ if (in_type == FILE_LEID3)
|
|
|
|
+ lhs = cvt_id3(ms, lhs);
|
|
if (off) {
|
|
if (off) {
|
|
switch (m->in_op & FILE_OPS_MASK) {
|
|
switch (m->in_op & FILE_OPS_MASK) {
|
|
case FILE_OPAND:
|
|
case FILE_OPAND:
|
|
@@ -1554,20 +1671,6 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
break;
|
|
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));
|
|
|
|
- if ((ms->flags & MAGIC_DEBUG) != 0)
|
|
|
|
- fprintf(stderr, "id3 offs=%u\n", offset);
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (m->flag & INDIROFFADD) {
|
|
if (m->flag & INDIROFFADD) {
|
|
offset += ms->c.li[cont_level-1].off;
|
|
offset += ms->c.li[cont_level-1].off;
|
|
if (offset == 0) {
|
|
if (offset == 0) {
|
|
@@ -1656,8 +1759,9 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
if ((pb = file_push_buffer(ms)) == NULL)
|
|
if ((pb = file_push_buffer(ms)) == NULL)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
|
|
+ (*indir_count)++;
|
|
rv = file_softmagic(ms, s + offset, nbytes - offset,
|
|
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)
|
|
if ((ms->flags & MAGIC_DEBUG) != 0)
|
|
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
|
|
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
|
|
@@ -1697,7 +1801,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
if (m->flag & NOSPACE)
|
|
if (m->flag & NOSPACE)
|
|
*need_separator = 0;
|
|
*need_separator = 0;
|
|
rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
|
|
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);
|
|
printed_something, need_separator, returnval);
|
|
if (rv != 1)
|
|
if (rv != 1)
|
|
*need_separator = oneed_separator;
|
|
*need_separator = oneed_separator;
|
|
@@ -1709,6 +1813,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
if (file_printf(ms, "%s", m->desc) == -1)
|
|
if (file_printf(ms, "%s", m->desc) == -1)
|
|
return -1;
|
|
return -1;
|
|
return 1;
|
|
return 1;
|
|
|
|
+ case FILE_DER:
|
|
case FILE_DEFAULT: /* nothing to check */
|
|
case FILE_DEFAULT: /* nothing to check */
|
|
case FILE_CLEAR:
|
|
case FILE_CLEAR:
|
|
default:
|
|
default:
|
|
@@ -1969,14 +2074,13 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
|
file_regerror(&rx, rc, ms);
|
|
file_regerror(&rx, rc, ms);
|
|
v = (uint64_t)-1;
|
|
v = (uint64_t)-1;
|
|
} else {
|
|
} else {
|
|
- regmatch_t pmatch[1];
|
|
|
|
|
|
+ regmatch_t pmatch;
|
|
size_t slen = ms->search.s_len;
|
|
size_t slen = ms->search.s_len;
|
|
-#ifndef REG_STARTEND
|
|
|
|
-#define REG_STARTEND 0
|
|
|
|
char *copy;
|
|
char *copy;
|
|
if (slen != 0) {
|
|
if (slen != 0) {
|
|
copy = malloc(slen);
|
|
copy = malloc(slen);
|
|
if (copy == NULL) {
|
|
if (copy == NULL) {
|
|
|
|
+ file_regfree(&rx);
|
|
file_error(ms, errno,
|
|
file_error(ms, errno,
|
|
"can't allocate %" SIZE_T_FORMAT "u bytes",
|
|
"can't allocate %" SIZE_T_FORMAT "u bytes",
|
|
slen);
|
|
slen);
|
|
@@ -1989,22 +2093,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
|
search = ms->search.s;
|
|
search = ms->search.s;
|
|
copy = NULL;
|
|
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,
|
|
rc = file_regexec(&rx, (const char *)search,
|
|
- 1, pmatch, REG_STARTEND);
|
|
|
|
-#if REG_STARTEND == 0
|
|
|
|
|
|
+ 1, &pmatch, 0);
|
|
free(copy);
|
|
free(copy);
|
|
-#endif
|
|
|
|
switch (rc) {
|
|
switch (rc) {
|
|
case 0:
|
|
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 =
|
|
ms->search.rm_len =
|
|
- (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
|
|
|
|
|
|
+ (size_t)(pmatch.rm_eo - pmatch.rm_so);
|
|
v = 0;
|
|
v = 0;
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -2027,6 +2124,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
|
case FILE_USE:
|
|
case FILE_USE:
|
|
case FILE_NAME:
|
|
case FILE_NAME:
|
|
return 1;
|
|
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:
|
|
default:
|
|
file_magerror(ms, "invalid type %d in magiccheck()", m->type);
|
|
file_magerror(ms, "invalid type %d in magiccheck()", m->type);
|
|
return -1;
|
|
return -1;
|
|
@@ -2126,12 +2233,12 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
|
private int
|
|
private int
|
|
handle_annotation(struct magic_set *ms, struct magic *m)
|
|
handle_annotation(struct magic_set *ms, struct magic *m)
|
|
{
|
|
{
|
|
- if (ms->flags & MAGIC_APPLE) {
|
|
|
|
|
|
+ if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
|
|
if (file_printf(ms, "%.8s", m->apple) == -1)
|
|
if (file_printf(ms, "%.8s", m->apple) == -1)
|
|
return -1;
|
|
return -1;
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
- if (ms->flags & MAGIC_EXTENSION) {
|
|
|
|
|
|
+ if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) {
|
|
if (file_printf(ms, "%s", m->ext) == -1)
|
|
if (file_printf(ms, "%s", m->ext) == -1)
|
|
return -1;
|
|
return -1;
|
|
return 1;
|
|
return 1;
|