|
@@ -32,7 +32,7 @@
|
|
|
#include "file.h"
|
|
|
|
|
|
#ifndef lint
|
|
|
-FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $")
|
|
|
+FILE_RCSID("@(#)$File: softmagic.c,v 1.259 2018/03/11 01:23:52 christos Exp $")
|
|
|
#endif /* lint */
|
|
|
|
|
|
#include "magic.h"
|
|
@@ -44,20 +44,26 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $")
|
|
|
#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 struct buffer *, 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 *,
|
|
|
+private int mget(struct magic_set *, struct magic *, const struct buffer *,
|
|
|
+ const unsigned char *, size_t,
|
|
|
+ size_t, unsigned int, int, int, int, uint16_t *,
|
|
|
uint16_t *, int *, int *, int *);
|
|
|
+private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
|
|
|
+ const struct buffer *, size_t, unsigned int);
|
|
|
private int magiccheck(struct magic_set *, struct magic *);
|
|
|
-private int32_t mprint(struct magic_set *, struct magic *);
|
|
|
-private int moffset(struct magic_set *, struct magic *, size_t, int32_t *);
|
|
|
+private int32_t mprint(struct magic_set *, struct magic *,
|
|
|
+ const struct buffer *);
|
|
|
+private int moffset(struct magic_set *, struct magic *, const struct buffer *,
|
|
|
+ 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 *, int);
|
|
|
+private int handle_annotation(struct magic_set *, struct magic *,
|
|
|
+ const struct buffer *, 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 *);
|
|
@@ -88,7 +94,7 @@ private int 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,
|
|
|
+file_softmagic(struct magic_set *ms, const struct buffer *b,
|
|
|
uint16_t *indir_count, uint16_t *name_count, int mode, int text)
|
|
|
{
|
|
|
struct mlist *ml;
|
|
@@ -105,7 +111,7 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
|
|
|
}
|
|
|
|
|
|
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, b, 0, mode,
|
|
|
text, 0, indir_count, name_count,
|
|
|
&printed_something, &need_separator, NULL)) != 0)
|
|
|
return rv;
|
|
@@ -118,18 +124,18 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
|
|
|
#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
|
|
|
|
|
|
private const char * __attribute__((__format_arg__(3)))
|
|
|
-file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
|
|
|
+file_fmtcheck(struct magic_set *ms, const char *desc, const char *def,
|
|
|
const char *file, size_t line)
|
|
|
{
|
|
|
- const char *ptr = fmtcheck(m->desc, def);
|
|
|
+ const char *ptr = fmtcheck(desc, def);
|
|
|
if (ptr == def)
|
|
|
file_magerror(ms,
|
|
|
"%s, %" SIZE_T_FORMAT "u: format `%s' does not match"
|
|
|
- " with `%s'", file, line, m->desc, def);
|
|
|
+ " with `%s'", file, line, desc, def);
|
|
|
return ptr;
|
|
|
}
|
|
|
#else
|
|
|
-#define F(a, b, c) fmtcheck((b)->desc, (c))
|
|
|
+#define F(a, b, c) fmtcheck((b), (c))
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
@@ -161,7 +167,7 @@ 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,
|
|
|
+ const struct buffer *b, size_t offset, int mode, int text,
|
|
|
int flip, uint16_t *indir_count, uint16_t *name_count,
|
|
|
int *printed_something, int *need_separator, int *returnval)
|
|
|
{
|
|
@@ -169,6 +175,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
|
|
|
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 */
|
|
|
+ struct buffer bb;
|
|
|
int print = (ms->flags & MAGIC_NODESC) == 0;
|
|
|
|
|
|
if (returnval == NULL)
|
|
@@ -196,12 +203,13 @@ flush:
|
|
|
continue; /* Skip to next top-level test*/
|
|
|
}
|
|
|
|
|
|
- ms->offset = m->offset;
|
|
|
+ if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
|
|
|
+ goto flush;
|
|
|
ms->line = m->lineno;
|
|
|
|
|
|
/* if main entry matches, print it... */
|
|
|
- switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
|
|
|
- flip, indir_count, name_count,
|
|
|
+ switch (mget(ms, m, b, bb.fbuf, bb.flen, offset, cont_level,
|
|
|
+ mode, text, flip, indir_count, name_count,
|
|
|
printed_something, need_separator, returnval)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
@@ -232,7 +240,7 @@ flush:
|
|
|
goto flush;
|
|
|
}
|
|
|
|
|
|
- if ((e = handle_annotation(ms, m, firstline)) != 0) {
|
|
|
+ if ((e = handle_annotation(ms, m, b, firstline)) != 0) {
|
|
|
*need_separator = 1;
|
|
|
*printed_something = 1;
|
|
|
*returnval = 1;
|
|
@@ -250,11 +258,10 @@ flush:
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- if (print && mprint(ms, m) == -1)
|
|
|
+ if (print && mprint(ms, m, b) == -1)
|
|
|
return -1;
|
|
|
|
|
|
- switch (moffset(ms, m, nbytes, &ms->c.li[cont_level].off)) {
|
|
|
+ switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
|
|
|
case -1:
|
|
|
case 0:
|
|
|
goto flush;
|
|
@@ -280,7 +287,8 @@ flush:
|
|
|
*/
|
|
|
cont_level = m->cont_level;
|
|
|
}
|
|
|
- ms->offset = m->offset;
|
|
|
+ if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
|
|
|
+ goto flush;
|
|
|
if (m->flag & OFFADD) {
|
|
|
ms->offset +=
|
|
|
ms->c.li[cont_level - 1].off;
|
|
@@ -293,9 +301,10 @@ flush:
|
|
|
continue;
|
|
|
}
|
|
|
#endif
|
|
|
- switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
|
|
|
- text, flip, indir_count, name_count,
|
|
|
- printed_something, need_separator, returnval)) {
|
|
|
+ switch (mget(ms, m, b, bb.fbuf, bb.flen, offset,
|
|
|
+ cont_level, mode, text, flip, indir_count,
|
|
|
+ name_count, printed_something, need_separator,
|
|
|
+ returnval)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 0:
|
|
@@ -330,7 +339,8 @@ flush:
|
|
|
} else
|
|
|
ms->c.li[cont_level].got_match = 1;
|
|
|
|
|
|
- if ((e = handle_annotation(ms, m, firstline)) != 0) {
|
|
|
+ if ((e = handle_annotation(ms, m, b, firstline))
|
|
|
+ != 0) {
|
|
|
*need_separator = 1;
|
|
|
*printed_something = 1;
|
|
|
*returnval = 1;
|
|
@@ -363,10 +373,10 @@ flush:
|
|
|
return -1;
|
|
|
*need_separator = 0;
|
|
|
}
|
|
|
- if (print && mprint(ms, m) == -1)
|
|
|
+ if (print && mprint(ms, m, b) == -1)
|
|
|
return -1;
|
|
|
|
|
|
- switch (moffset(ms, m, nbytes,
|
|
|
+ switch (moffset(ms, m, &bb,
|
|
|
&ms->c.li[cont_level].off)) {
|
|
|
case -1:
|
|
|
case 0:
|
|
@@ -404,19 +414,19 @@ flush:
|
|
|
}
|
|
|
|
|
|
private int
|
|
|
-check_fmt(struct magic_set *ms, struct magic *m)
|
|
|
+check_fmt(struct magic_set *ms, const char *fmt)
|
|
|
{
|
|
|
file_regex_t rx;
|
|
|
int rc, rv = -1;
|
|
|
|
|
|
- if (strchr(m->desc, '%') == NULL)
|
|
|
+ if (strchr(fmt, '%') == NULL)
|
|
|
return 0;
|
|
|
|
|
|
rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
|
|
|
if (rc) {
|
|
|
file_regerror(&rx, rc, ms);
|
|
|
} else {
|
|
|
- rc = file_regexec(&rx, m->desc, 0, 0, 0);
|
|
|
+ rc = file_regexec(&rx, fmt, 0, 0, 0);
|
|
|
rv = !rc;
|
|
|
}
|
|
|
file_regfree(&rx);
|
|
@@ -442,30 +452,91 @@ strndup(const char *str, size_t n)
|
|
|
}
|
|
|
#endif /* HAVE_STRNDUP */
|
|
|
|
|
|
+static int
|
|
|
+varexpand(char *buf, size_t len, const struct buffer *b, const char *str)
|
|
|
+{
|
|
|
+ const char *ptr, *sptr, *e, *t, *ee, *et;
|
|
|
+ size_t l;
|
|
|
+
|
|
|
+ for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) {
|
|
|
+ l = (size_t)(ptr - sptr);
|
|
|
+ if (l >= len)
|
|
|
+ return -1;
|
|
|
+ memcpy(buf, sptr, l);
|
|
|
+ buf += l;
|
|
|
+ len -= l;
|
|
|
+ ptr += 2;
|
|
|
+ if (!*ptr || ptr[1] != '?')
|
|
|
+ return -1;
|
|
|
+ for (et = t = ptr + 2; *et && *et != ':'; et++)
|
|
|
+ continue;
|
|
|
+ if (*et != ':')
|
|
|
+ return -1;
|
|
|
+ for (ee = e = et + 1; *ee && *ee != '}'; ee++)
|
|
|
+ continue;
|
|
|
+ if (*ee != '}')
|
|
|
+ return -1;
|
|
|
+ switch (*ptr) {
|
|
|
+ case 'x':
|
|
|
+ if (b->st.st_mode & 0111) {
|
|
|
+ ptr = t;
|
|
|
+ l = et - t;
|
|
|
+ } else {
|
|
|
+ ptr = e;
|
|
|
+ l = ee - e;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (l >= len)
|
|
|
+ return -1;
|
|
|
+ memcpy(buf, ptr, l);
|
|
|
+ buf += l;
|
|
|
+ len -= l;
|
|
|
+ sptr = ee + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ l = strlen(sptr);
|
|
|
+ if (l >= len)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ memcpy(buf, sptr, l);
|
|
|
+ buf[l] = '\0';
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
private int32_t
|
|
|
-mprint(struct magic_set *ms, struct magic *m)
|
|
|
+mprint(struct magic_set *ms, struct magic *m, const struct buffer *b)
|
|
|
{
|
|
|
uint64_t v;
|
|
|
float vf;
|
|
|
double vd;
|
|
|
int64_t t = 0;
|
|
|
- char buf[128], tbuf[26], sbuf[512];
|
|
|
+ char buf[128], tbuf[26], sbuf[512], ebuf[512];
|
|
|
+ const char *desc;
|
|
|
union VALUETYPE *p = &ms->ms_value;
|
|
|
|
|
|
+ if (varexpand(ebuf, sizeof(ebuf), b, m->desc) == -1)
|
|
|
+ desc = m->desc;
|
|
|
+ else
|
|
|
+ desc = ebuf;
|
|
|
+
|
|
|
switch (m->type) {
|
|
|
case FILE_BYTE:
|
|
|
v = file_signextend(ms, m, (uint64_t)p->b);
|
|
|
- switch (check_fmt(ms, m)) {
|
|
|
+ switch (check_fmt(ms, desc)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 1:
|
|
|
(void)snprintf(buf, sizeof(buf), "%d",
|
|
|
(unsigned char)v);
|
|
|
- if (file_printf(ms, F(ms, m, "%s"), buf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
default:
|
|
|
- if (file_printf(ms, F(ms, m, "%d"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%d"),
|
|
|
(unsigned char) v) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
@@ -477,17 +548,17 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BESHORT:
|
|
|
case FILE_LESHORT:
|
|
|
v = file_signextend(ms, m, (uint64_t)p->h);
|
|
|
- switch (check_fmt(ms, m)) {
|
|
|
+ switch (check_fmt(ms, desc)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 1:
|
|
|
(void)snprintf(buf, sizeof(buf), "%u",
|
|
|
(unsigned short)v);
|
|
|
- if (file_printf(ms, F(ms, m, "%s"), buf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
default:
|
|
|
- if (file_printf(ms, F(ms, m, "%u"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%u"),
|
|
|
(unsigned short) v) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
@@ -500,16 +571,16 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_LELONG:
|
|
|
case FILE_MELONG:
|
|
|
v = file_signextend(ms, m, (uint64_t)p->l);
|
|
|
- switch (check_fmt(ms, m)) {
|
|
|
+ switch (check_fmt(ms, desc)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 1:
|
|
|
(void)snprintf(buf, sizeof(buf), "%u", (uint32_t) v);
|
|
|
- if (file_printf(ms, F(ms, m, "%s"), buf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
default:
|
|
|
- if (file_printf(ms, F(ms, m, "%u"), (uint32_t) v) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%u"), (uint32_t) v) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
@@ -520,17 +591,17 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BEQUAD:
|
|
|
case FILE_LEQUAD:
|
|
|
v = file_signextend(ms, m, p->q);
|
|
|
- switch (check_fmt(ms, m)) {
|
|
|
+ switch (check_fmt(ms, desc)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 1:
|
|
|
(void)snprintf(buf, sizeof(buf), "%" INT64_T_FORMAT "u",
|
|
|
(unsigned long long)v);
|
|
|
- if (file_printf(ms, F(ms, m, "%s"), buf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
default:
|
|
|
- if (file_printf(ms, F(ms, m, "%" INT64_T_FORMAT "u"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%" INT64_T_FORMAT "u"),
|
|
|
(unsigned long long) v) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
@@ -543,7 +614,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BESTRING16:
|
|
|
case FILE_LESTRING16:
|
|
|
if (m->reln == '=' || m->reln == '!') {
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_printable(sbuf, sizeof(sbuf), m->value.s))
|
|
|
== -1)
|
|
|
return -1;
|
|
@@ -571,7 +642,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
*++last = '\0';
|
|
|
}
|
|
|
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_printable(sbuf, sizeof(sbuf), str)) == -1)
|
|
|
return -1;
|
|
|
|
|
@@ -584,7 +655,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BEDATE:
|
|
|
case FILE_LEDATE:
|
|
|
case FILE_MEDATE:
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_fmttime(p->l, 0, tbuf)) == -1)
|
|
|
return -1;
|
|
|
t = ms->offset + sizeof(uint32_t);
|
|
@@ -594,7 +665,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BELDATE:
|
|
|
case FILE_LELDATE:
|
|
|
case FILE_MELDATE:
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_fmttime(p->l, FILE_T_LOCAL, tbuf)) == -1)
|
|
|
return -1;
|
|
|
t = ms->offset + sizeof(uint32_t);
|
|
@@ -603,7 +674,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_QDATE:
|
|
|
case FILE_BEQDATE:
|
|
|
case FILE_LEQDATE:
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_fmttime(p->q, 0, tbuf)) == -1)
|
|
|
return -1;
|
|
|
t = ms->offset + sizeof(uint64_t);
|
|
@@ -612,7 +683,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_QLDATE:
|
|
|
case FILE_BEQLDATE:
|
|
|
case FILE_LEQLDATE:
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1)
|
|
|
return -1;
|
|
|
t = ms->offset + sizeof(uint64_t);
|
|
@@ -621,7 +692,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_QWDATE:
|
|
|
case FILE_BEQWDATE:
|
|
|
case FILE_LEQWDATE:
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1)
|
|
|
return -1;
|
|
|
t = ms->offset + sizeof(uint64_t);
|
|
@@ -631,16 +702,16 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BEFLOAT:
|
|
|
case FILE_LEFLOAT:
|
|
|
vf = p->f;
|
|
|
- switch (check_fmt(ms, m)) {
|
|
|
+ switch (check_fmt(ms, desc)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 1:
|
|
|
(void)snprintf(buf, sizeof(buf), "%g", vf);
|
|
|
- if (file_printf(ms, F(ms, m, "%s"), buf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
default:
|
|
|
- if (file_printf(ms, F(ms, m, "%g"), vf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%g"), vf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
@@ -651,16 +722,16 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
case FILE_BEDOUBLE:
|
|
|
case FILE_LEDOUBLE:
|
|
|
vd = p->d;
|
|
|
- switch (check_fmt(ms, m)) {
|
|
|
+ switch (check_fmt(ms, desc)) {
|
|
|
case -1:
|
|
|
return -1;
|
|
|
case 1:
|
|
|
(void)snprintf(buf, sizeof(buf), "%g", vd);
|
|
|
- if (file_printf(ms, F(ms, m, "%s"), buf) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
default:
|
|
|
- if (file_printf(ms, F(ms, m, "%g"), vd) == -1)
|
|
|
+ if (file_printf(ms, F(ms, desc, "%g"), vd) == -1)
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
@@ -677,7 +748,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
file_oomem(ms, ms->search.rm_len);
|
|
|
return -1;
|
|
|
}
|
|
|
- rval = file_printf(ms, F(ms, m, "%s"),
|
|
|
+ rval = file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_printable(sbuf, sizeof(sbuf), cp));
|
|
|
free(cp);
|
|
|
|
|
@@ -704,7 +775,7 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
t = ms->offset;
|
|
|
break;
|
|
|
case FILE_DER:
|
|
|
- if (file_printf(ms, F(ms, m, "%s"),
|
|
|
+ if (file_printf(ms, F(ms, desc, "%s"),
|
|
|
file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1)
|
|
|
return -1;
|
|
|
t = ms->offset;
|
|
@@ -717,8 +788,10 @@ mprint(struct magic_set *ms, struct magic *m)
|
|
|
}
|
|
|
|
|
|
private int
|
|
|
-moffset(struct magic_set *ms, struct magic *m, size_t nbytes, int32_t *op)
|
|
|
+moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
|
|
|
+ int32_t *op)
|
|
|
{
|
|
|
+ size_t nbytes = b->flen;
|
|
|
int32_t o;
|
|
|
|
|
|
switch (m->type) {
|
|
@@ -1232,7 +1305,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
|
b++;
|
|
|
}
|
|
|
if (lines)
|
|
|
- last = RCAST(const char *, s) + bytecnt;
|
|
|
+ last = end;
|
|
|
|
|
|
ms->search.s = buf;
|
|
|
ms->search.s_len = last - buf;
|
|
@@ -1337,12 +1410,58 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off)
|
|
|
}
|
|
|
|
|
|
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_count, uint16_t *name_count,
|
|
|
+msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
|
|
|
+ const struct buffer *b, size_t o, unsigned int cont_level)
|
|
|
+{
|
|
|
+ if (m->offset < 0) {
|
|
|
+ if (cont_level > 0) {
|
|
|
+ if (m->flag & (OFFADD|INDIROFFADD))
|
|
|
+ goto normal;
|
|
|
+#if 0
|
|
|
+ file_error(ms, 0, "negative offset %d at continuation"
|
|
|
+ "level %u", m->offset, cont_level);
|
|
|
+ return -1;
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ if (buffer_fill(b) == -1)
|
|
|
+ return -1;
|
|
|
+ if (o != 0) {
|
|
|
+ // Not yet!
|
|
|
+ file_magerror(ms, "non zero offset %zu at"
|
|
|
+ " level %u", o, cont_level);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if ((size_t)-m->offset > b->elen)
|
|
|
+ return -1;
|
|
|
+ buffer_init(bb, -1, b->ebuf, b->elen);
|
|
|
+ ms->eoffset = ms->offset = b->elen + m->offset;
|
|
|
+ } else {
|
|
|
+ if (cont_level == 0) {
|
|
|
+normal:
|
|
|
+ // XXX: Pass real fd, then who frees bb?
|
|
|
+ buffer_init(bb, -1, b->fbuf, b->flen);
|
|
|
+ ms->offset = m->offset;
|
|
|
+ ms->eoffset = 0;
|
|
|
+ } else {
|
|
|
+ ms->offset = ms->eoffset + m->offset;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ((ms->flags & MAGIC_DEBUG) != 0) {
|
|
|
+ fprintf(stderr, "bb=[%p,%zu], %d [b=%p,%zu], [o=%#x, c=%d]\n",
|
|
|
+ bb->fbuf, bb->flen, ms->offset, b->fbuf, b->flen,
|
|
|
+ m->offset, cont_level);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+private int
|
|
|
+mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
|
|
|
+ const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
|
|
|
+ int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
|
|
|
int *printed_something, int *need_separator, int *returnval)
|
|
|
{
|
|
|
uint32_t offset = ms->offset;
|
|
|
+ struct buffer bb;
|
|
|
intmax_t lhs;
|
|
|
file_pushbuf_t *pb;
|
|
|
int rv, oneed_separator, in_type;
|
|
@@ -1362,6 +1481,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
|
|
|
(uint32_t)nbytes, m) == -1)
|
|
|
return -1;
|
|
@@ -1559,7 +1680,10 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
return -1;
|
|
|
|
|
|
(*indir_count)++;
|
|
|
- rv = file_softmagic(ms, s + offset, nbytes - offset,
|
|
|
+ bb = *b;
|
|
|
+ bb.fbuf = s + offset;
|
|
|
+ bb.flen = nbytes - offset;
|
|
|
+ rv = file_softmagic(ms, &bb,
|
|
|
indir_count, name_count, BINTEST, text);
|
|
|
|
|
|
if ((ms->flags & MAGIC_DEBUG) != 0)
|
|
@@ -1571,7 +1695,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
|
|
|
if (rv == 1) {
|
|
|
if ((ms->flags & MAGIC_NODESC) == 0 &&
|
|
|
- file_printf(ms, F(ms, m, "%u"), offset) == -1) {
|
|
|
+ file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) {
|
|
|
free(rbuf);
|
|
|
return -1;
|
|
|
}
|
|
@@ -1599,12 +1723,12 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
oneed_separator = *need_separator;
|
|
|
if (m->flag & NOSPACE)
|
|
|
*need_separator = 0;
|
|
|
- rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
|
|
|
+ rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
|
|
|
mode, text, flip, indir_count, name_count,
|
|
|
printed_something, need_separator, returnval);
|
|
|
if (rv != 1)
|
|
|
*need_separator = oneed_separator;
|
|
|
- return 1;
|
|
|
+ return rv;
|
|
|
|
|
|
case FILE_NAME:
|
|
|
if (ms->flags & MAGIC_NODESC)
|
|
@@ -2035,7 +2159,8 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
|
|
}
|
|
|
|
|
|
private int
|
|
|
-handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
|
|
|
+handle_annotation(struct magic_set *ms, struct magic *m, const struct buffer *b,
|
|
|
+ int firstline)
|
|
|
{
|
|
|
if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
|
|
|
if (!firstline && file_printf(ms, "\n- ") == -1)
|
|
@@ -2052,9 +2177,15 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
|
|
|
return 1;
|
|
|
}
|
|
|
if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
|
|
|
+ char buf[1024];
|
|
|
+ const char *p;
|
|
|
if (!firstline && file_printf(ms, "\n- ") == -1)
|
|
|
return -1;
|
|
|
- if (file_printf(ms, "%s", m->mimetype) == -1)
|
|
|
+ if (varexpand(buf, sizeof(buf), b, m->mimetype) == -1)
|
|
|
+ p = m->mimetype;
|
|
|
+ else
|
|
|
+ p = buf;
|
|
|
+ if (file_printf(ms, "%s", p) == -1)
|
|
|
return -1;
|
|
|
return 1;
|
|
|
}
|