|
@@ -32,7 +32,7 @@
|
|
#include "file.h"
|
|
#include "file.h"
|
|
|
|
|
|
#ifndef lint
|
|
#ifndef lint
|
|
-FILE_RCSID("@(#)$File: apprentice.c,v 1.284 2019/06/29 22:31:04 christos Exp $")
|
|
|
|
|
|
+FILE_RCSID("@(#)$File: apprentice.c,v 1.297 2020/05/09 18:57:15 christos Exp $")
|
|
#endif /* lint */
|
|
#endif /* lint */
|
|
|
|
|
|
#include "magic.h"
|
|
#include "magic.h"
|
|
@@ -120,6 +120,7 @@ private void apprentice_list(struct mlist *, int );
|
|
private struct magic_map *apprentice_load(struct magic_set *,
|
|
private struct magic_map *apprentice_load(struct magic_set *,
|
|
const char *, int);
|
|
const char *, int);
|
|
private struct mlist *mlist_alloc(void);
|
|
private struct mlist *mlist_alloc(void);
|
|
|
|
+private void mlist_free_all(struct magic_set *);
|
|
private void mlist_free(struct mlist *);
|
|
private void mlist_free(struct mlist *);
|
|
private void byteswap(struct magic *, uint32_t);
|
|
private void byteswap(struct magic *, uint32_t);
|
|
private void bs1(struct magic *);
|
|
private void bs1(struct magic *);
|
|
@@ -137,10 +138,14 @@ private int apprentice_compile(struct magic_set *, struct magic_map *,
|
|
private int check_format_type(const char *, int, const char **);
|
|
private int check_format_type(const char *, int, const char **);
|
|
private int check_format(struct magic_set *, struct magic *);
|
|
private int check_format(struct magic_set *, struct magic *);
|
|
private int get_op(char);
|
|
private int get_op(char);
|
|
-private int parse_mime(struct magic_set *, struct magic_entry *, const char *);
|
|
|
|
-private int parse_strength(struct magic_set *, struct magic_entry *, const char *);
|
|
|
|
-private int parse_apple(struct magic_set *, struct magic_entry *, const char *);
|
|
|
|
-private int parse_ext(struct magic_set *, struct magic_entry *, const char *);
|
|
|
|
|
|
+private int parse_mime(struct magic_set *, struct magic_entry *, const char *,
|
|
|
|
+ size_t);
|
|
|
|
+private int parse_strength(struct magic_set *, struct magic_entry *,
|
|
|
|
+ const char *, size_t);
|
|
|
|
+private int parse_apple(struct magic_set *, struct magic_entry *, const char *,
|
|
|
|
+ size_t);
|
|
|
|
+private int parse_ext(struct magic_set *, struct magic_entry *, const char *,
|
|
|
|
+ size_t);
|
|
|
|
|
|
|
|
|
|
private size_t magicsize = sizeof(struct magic);
|
|
private size_t magicsize = sizeof(struct magic);
|
|
@@ -150,7 +155,8 @@ private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
|
|
private struct {
|
|
private struct {
|
|
const char *name;
|
|
const char *name;
|
|
size_t len;
|
|
size_t len;
|
|
- int (*fun)(struct magic_set *, struct magic_entry *, const char *);
|
|
|
|
|
|
+ int (*fun)(struct magic_set *, struct magic_entry *, const char *,
|
|
|
|
+ size_t);
|
|
} bang[] = {
|
|
} bang[] = {
|
|
#define DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
|
|
#define DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
|
|
DECLARE_FIELD(mime),
|
|
DECLARE_FIELD(mime),
|
|
@@ -260,6 +266,8 @@ static const struct type_tbl_s type_tbl[] = {
|
|
{ XX("use"), FILE_USE, FILE_FMT_NONE },
|
|
{ XX("use"), FILE_USE, FILE_FMT_NONE },
|
|
{ XX("clear"), FILE_CLEAR, FILE_FMT_NONE },
|
|
{ XX("clear"), FILE_CLEAR, FILE_FMT_NONE },
|
|
{ XX("der"), FILE_DER, FILE_FMT_STR },
|
|
{ XX("der"), FILE_DER, FILE_FMT_STR },
|
|
|
|
+ { XX("guid"), FILE_GUID, FILE_FMT_STR },
|
|
|
|
+ { XX("offset"), FILE_OFFSET, FILE_FMT_QUAD },
|
|
{ XX_NULL, FILE_INVALID, FILE_FMT_NONE },
|
|
{ XX_NULL, FILE_INVALID, FILE_FMT_NONE },
|
|
};
|
|
};
|
|
|
|
|
|
@@ -451,8 +459,6 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
|
|
|
|
|
|
#ifndef COMPILE_ONLY
|
|
#ifndef COMPILE_ONLY
|
|
map = apprentice_map(ms, fn);
|
|
map = apprentice_map(ms, fn);
|
|
- if (map == RCAST(struct magic_map *, -1))
|
|
|
|
- return -1;
|
|
|
|
if (map == NULL) {
|
|
if (map == NULL) {
|
|
if (ms->flags & MAGIC_CHECK)
|
|
if (ms->flags & MAGIC_CHECK)
|
|
file_magwarn(ms, "using regular magic file `%s'", fn);
|
|
file_magwarn(ms, "using regular magic file `%s'", fn);
|
|
@@ -463,6 +469,11 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
|
|
|
|
|
|
for (i = 0; i < MAGIC_SETS; i++) {
|
|
for (i = 0; i < MAGIC_SETS; i++) {
|
|
if (add_mlist(ms->mlist[i], map, i) == -1) {
|
|
if (add_mlist(ms->mlist[i], map, i) == -1) {
|
|
|
|
+ /* failed to add to any list, free explicitly */
|
|
|
|
+ if (i == 0)
|
|
|
|
+ apprentice_unmap(map);
|
|
|
|
+ else
|
|
|
|
+ mlist_free_all(ms);
|
|
file_oomem(ms, sizeof(*ml));
|
|
file_oomem(ms, sizeof(*ml));
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -513,6 +524,7 @@ file_ms_alloc(int flags)
|
|
}
|
|
}
|
|
|
|
|
|
ms->o.buf = ms->o.pbuf = NULL;
|
|
ms->o.buf = ms->o.pbuf = NULL;
|
|
|
|
+ ms->o.blen = 0;
|
|
len = (ms->c.len = 10) * sizeof(*ms->c.li);
|
|
len = (ms->c.len = 10) * sizeof(*ms->c.li);
|
|
|
|
|
|
if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
|
|
if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
|
|
@@ -582,6 +594,17 @@ mlist_alloc(void)
|
|
}
|
|
}
|
|
|
|
|
|
private void
|
|
private void
|
|
|
|
+mlist_free_all(struct magic_set *ms)
|
|
|
|
+{
|
|
|
|
+ size_t i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < MAGIC_SETS; i++) {
|
|
|
|
+ mlist_free(ms->mlist[i]);
|
|
|
|
+ ms->mlist[i] = NULL;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+private void
|
|
mlist_free_one(struct mlist *ml)
|
|
mlist_free_one(struct mlist *ml)
|
|
{
|
|
{
|
|
if (ml->map)
|
|
if (ml->map)
|
|
@@ -597,9 +620,10 @@ mlist_free(struct mlist *mlist)
|
|
if (mlist == NULL)
|
|
if (mlist == NULL)
|
|
return;
|
|
return;
|
|
|
|
|
|
- for (ml = mlist->next; ml != mlist; ml = next) {
|
|
|
|
|
|
+ for (ml = mlist->next; ml != mlist;) {
|
|
next = ml->next;
|
|
next = ml->next;
|
|
mlist_free_one(ml);
|
|
mlist_free_one(ml);
|
|
|
|
+ ml = next;
|
|
}
|
|
}
|
|
mlist_free_one(mlist);
|
|
mlist_free_one(mlist);
|
|
}
|
|
}
|
|
@@ -644,10 +668,7 @@ buffer_apprentice(struct magic_set *ms, struct magic **bufs,
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
fail:
|
|
fail:
|
|
- for (i = 0; i < MAGIC_SETS; i++) {
|
|
|
|
- mlist_free(ms->mlist[i]);
|
|
|
|
- ms->mlist[i] = NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ mlist_free_all(ms);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -658,7 +679,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
|
|
{
|
|
{
|
|
char *p, *mfn;
|
|
char *p, *mfn;
|
|
int fileerr, errs = -1;
|
|
int fileerr, errs = -1;
|
|
- size_t i;
|
|
|
|
|
|
+ size_t i, j;
|
|
|
|
|
|
(void)file_reset(ms, 0);
|
|
(void)file_reset(ms, 0);
|
|
|
|
|
|
@@ -676,9 +697,9 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
|
|
mlist_free(ms->mlist[i]);
|
|
mlist_free(ms->mlist[i]);
|
|
if ((ms->mlist[i] = mlist_alloc()) == NULL) {
|
|
if ((ms->mlist[i] = mlist_alloc()) == NULL) {
|
|
file_oomem(ms, sizeof(*ms->mlist[i]));
|
|
file_oomem(ms, sizeof(*ms->mlist[i]));
|
|
- while (i-- > 0) {
|
|
|
|
- mlist_free(ms->mlist[i]);
|
|
|
|
- ms->mlist[i] = NULL;
|
|
|
|
|
|
+ for (j = 0; j < i; j++) {
|
|
|
|
+ mlist_free(ms->mlist[j]);
|
|
|
|
+ ms->mlist[j] = NULL;
|
|
}
|
|
}
|
|
free(mfn);
|
|
free(mfn);
|
|
return -1;
|
|
return -1;
|
|
@@ -829,9 +850,14 @@ typesize(int type)
|
|
case FILE_DOUBLE:
|
|
case FILE_DOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
|
|
+ case FILE_OFFSET:
|
|
return 8;
|
|
return 8;
|
|
|
|
+
|
|
|
|
+ case FILE_GUID:
|
|
|
|
+ return 16;
|
|
|
|
+
|
|
default:
|
|
default:
|
|
- return CAST(size_t, ~0);
|
|
|
|
|
|
+ return FILE_BADSIZE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -885,8 +911,10 @@ apprentice_magic_strength(const struct magic *m)
|
|
case FILE_DOUBLE:
|
|
case FILE_DOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
|
|
+ case FILE_GUID:
|
|
|
|
+ case FILE_OFFSET:
|
|
ts = typesize(m->type);
|
|
ts = typesize(m->type);
|
|
- if (ts == CAST(size_t, ~0))
|
|
|
|
|
|
+ if (ts == FILE_BADSIZE)
|
|
abort();
|
|
abort();
|
|
val += ts * MULT;
|
|
val += ts * MULT;
|
|
break;
|
|
break;
|
|
@@ -1077,6 +1105,8 @@ set_test_type(struct magic *mstart, struct magic *m)
|
|
case FILE_BEDOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
case FILE_DER:
|
|
case FILE_DER:
|
|
|
|
+ case FILE_GUID:
|
|
|
|
+ case FILE_OFFSET:
|
|
mstart->flag |= BINTEST;
|
|
mstart->flag |= BINTEST;
|
|
break;
|
|
break;
|
|
case FILE_STRING:
|
|
case FILE_STRING:
|
|
@@ -1201,7 +1231,8 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
if ((*bang[i].fun)(ms, &me,
|
|
if ((*bang[i].fun)(ms, &me,
|
|
- line + bang[i].len + 2) != 0) {
|
|
|
|
|
|
+ line + bang[i].len + 2,
|
|
|
|
+ len - bang[i].len - 2) != 0) {
|
|
(*errs)++;
|
|
(*errs)++;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
@@ -1381,9 +1412,10 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
|
|
}
|
|
}
|
|
if (files >= maxfiles) {
|
|
if (files >= maxfiles) {
|
|
size_t mlen;
|
|
size_t mlen;
|
|
|
|
+ char **nfilearr;
|
|
maxfiles = (maxfiles + 1) * 2;
|
|
maxfiles = (maxfiles + 1) * 2;
|
|
mlen = maxfiles * sizeof(*filearr);
|
|
mlen = maxfiles * sizeof(*filearr);
|
|
- if ((filearr = CAST(char **,
|
|
|
|
|
|
+ if ((nfilearr = CAST(char **,
|
|
realloc(filearr, mlen))) == NULL) {
|
|
realloc(filearr, mlen))) == NULL) {
|
|
file_oomem(ms, mlen);
|
|
file_oomem(ms, mlen);
|
|
free(mfn);
|
|
free(mfn);
|
|
@@ -1391,6 +1423,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
|
|
errs++;
|
|
errs++;
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
+ filearr = nfilearr;
|
|
}
|
|
}
|
|
filearr[files++] = mfn;
|
|
filearr[files++] = mfn;
|
|
}
|
|
}
|
|
@@ -1402,6 +1435,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
|
|
free(filearr[i]);
|
|
free(filearr[i]);
|
|
}
|
|
}
|
|
free(filearr);
|
|
free(filearr);
|
|
|
|
+ filearr = NULL;
|
|
}
|
|
}
|
|
} else
|
|
} else
|
|
load_1(ms, action, fn, &errs, mset);
|
|
load_1(ms, action, fn, &errs, mset);
|
|
@@ -1436,6 +1470,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
|
|
}
|
|
}
|
|
|
|
|
|
out:
|
|
out:
|
|
|
|
+ free(filearr);
|
|
for (j = 0; j < MAGIC_SETS; j++)
|
|
for (j = 0; j < MAGIC_SETS; j++)
|
|
magic_entry_free(mset[j].me, mset[j].count);
|
|
magic_entry_free(mset[j].me, mset[j].count);
|
|
|
|
|
|
@@ -1499,6 +1534,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
|
|
case FILE_DOUBLE:
|
|
case FILE_DOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_BEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
case FILE_LEDOUBLE:
|
|
|
|
+ case FILE_OFFSET:
|
|
v = CAST(int64_t, v);
|
|
v = CAST(int64_t, v);
|
|
break;
|
|
break;
|
|
case FILE_STRING:
|
|
case FILE_STRING:
|
|
@@ -1513,12 +1549,13 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
|
|
case FILE_USE:
|
|
case FILE_USE:
|
|
case FILE_CLEAR:
|
|
case FILE_CLEAR:
|
|
case FILE_DER:
|
|
case FILE_DER:
|
|
|
|
+ case FILE_GUID:
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
if (ms->flags & MAGIC_CHECK)
|
|
if (ms->flags & MAGIC_CHECK)
|
|
file_magwarn(ms, "cannot happen: m->type=%d\n",
|
|
file_magwarn(ms, "cannot happen: m->type=%d\n",
|
|
m->type);
|
|
m->type);
|
|
- return ~0U;
|
|
|
|
|
|
+ return FILE_BADSIZE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return v;
|
|
return v;
|
|
@@ -1920,6 +1957,10 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
}
|
|
}
|
|
|
|
|
|
/* get offset, then skip over it */
|
|
/* get offset, then skip over it */
|
|
|
|
+ if (*l == '-') {
|
|
|
|
+ ++l; /* step over */
|
|
|
|
+ m->flag |= OFFNEGATIVE;
|
|
|
|
+ }
|
|
m->offset = CAST(int32_t, strtol(l, &t, 0));
|
|
m->offset = CAST(int32_t, strtol(l, &t, 0));
|
|
if (l == t) {
|
|
if (l == t) {
|
|
if (ms->flags & MAGIC_CHECK)
|
|
if (ms->flags & MAGIC_CHECK)
|
|
@@ -2224,7 +2265,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
* if valid
|
|
* if valid
|
|
*/
|
|
*/
|
|
private int
|
|
private int
|
|
-parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
|
|
|
|
|
|
+parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
|
|
+ size_t len __attribute__((__unused__)))
|
|
{
|
|
{
|
|
const char *l = line;
|
|
const char *l = line;
|
|
char *el;
|
|
char *el;
|
|
@@ -2286,7 +2328,8 @@ goodchar(unsigned char x, const char *extra)
|
|
|
|
|
|
private int
|
|
private int
|
|
parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
- off_t off, size_t len, const char *name, const char *extra, int nt)
|
|
|
|
|
|
+ size_t llen, off_t off, size_t len, const char *name, const char *extra,
|
|
|
|
+ int nt)
|
|
{
|
|
{
|
|
size_t i;
|
|
size_t i;
|
|
const char *l = line;
|
|
const char *l = line;
|
|
@@ -2307,7 +2350,8 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
}
|
|
}
|
|
|
|
|
|
EATAB;
|
|
EATAB;
|
|
- for (i = 0; *l && i < len && goodchar(*l, extra); buf[i++] = *l++)
|
|
|
|
|
|
+ for (i = 0; *l && i < llen && i < len && goodchar(*l, extra);
|
|
|
|
+ buf[i++] = *l++)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
if (i == len && *l) {
|
|
if (i == len && *l) {
|
|
@@ -2336,11 +2380,12 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
* magic[index - 1]
|
|
* magic[index - 1]
|
|
*/
|
|
*/
|
|
private int
|
|
private int
|
|
-parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
|
|
|
|
|
|
+parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
|
|
+ size_t len)
|
|
{
|
|
{
|
|
struct magic *m = &me->mp[0];
|
|
struct magic *m = &me->mp[0];
|
|
|
|
|
|
- return parse_extra(ms, me, line,
|
|
|
|
|
|
+ return parse_extra(ms, me, line, len,
|
|
CAST(off_t, offsetof(struct magic, apple)),
|
|
CAST(off_t, offsetof(struct magic, apple)),
|
|
sizeof(m->apple), "APPLE", "!+-./?", 0);
|
|
sizeof(m->apple), "APPLE", "!+-./?", 0);
|
|
}
|
|
}
|
|
@@ -2349,11 +2394,12 @@ parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
|
|
* Parse a comma-separated list of extensions
|
|
* Parse a comma-separated list of extensions
|
|
*/
|
|
*/
|
|
private int
|
|
private int
|
|
-parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line)
|
|
|
|
|
|
+parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
|
|
+ size_t len)
|
|
{
|
|
{
|
|
struct magic *m = &me->mp[0];
|
|
struct magic *m = &me->mp[0];
|
|
|
|
|
|
- return parse_extra(ms, me, line,
|
|
|
|
|
|
+ return parse_extra(ms, me, line, len,
|
|
CAST(off_t, offsetof(struct magic, ext)),
|
|
CAST(off_t, offsetof(struct magic, ext)),
|
|
sizeof(m->ext), "EXTENSION", ",!+-/@?_$", 0);
|
|
sizeof(m->ext), "EXTENSION", ",!+-/@?_$", 0);
|
|
}
|
|
}
|
|
@@ -2363,11 +2409,12 @@ parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line)
|
|
* if valid
|
|
* if valid
|
|
*/
|
|
*/
|
|
private int
|
|
private int
|
|
-parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line)
|
|
|
|
|
|
+parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line,
|
|
|
|
+ size_t len)
|
|
{
|
|
{
|
|
struct magic *m = &me->mp[0];
|
|
struct magic *m = &me->mp[0];
|
|
|
|
|
|
- return parse_extra(ms, me, line,
|
|
|
|
|
|
+ return parse_extra(ms, me, line, len,
|
|
CAST(off_t, offsetof(struct magic, mimetype)),
|
|
CAST(off_t, offsetof(struct magic, mimetype)),
|
|
sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
|
|
sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
|
|
}
|
|
}
|
|
@@ -2684,6 +2731,11 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
|
|
if (errno == 0)
|
|
if (errno == 0)
|
|
*p = ep;
|
|
*p = ep;
|
|
return 0;
|
|
return 0;
|
|
|
|
+ case FILE_GUID:
|
|
|
|
+ if (file_parse_guid(*p, m->value.guid) == -1)
|
|
|
|
+ return -1;
|
|
|
|
+ *p += FILE_GUID_SIZE - 1;
|
|
|
|
+ return 0;
|
|
default:
|
|
default:
|
|
errno = 0;
|
|
errno = 0;
|
|
ull = CAST(uint64_t, strtoull(*p, &ep, 0));
|
|
ull = CAST(uint64_t, strtoull(*p, &ep, 0));
|
|
@@ -2695,7 +2747,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
|
|
uint64_t x;
|
|
uint64_t x;
|
|
const char *q;
|
|
const char *q;
|
|
|
|
|
|
- if (ts == CAST(size_t, ~0)) {
|
|
|
|
|
|
+ if (ts == FILE_BADSIZE) {
|
|
file_magwarn(ms,
|
|
file_magwarn(ms,
|
|
"Expected numeric type got `%s'",
|
|
"Expected numeric type got `%s'",
|
|
type_tbl[m->type].name);
|
|
type_tbl[m->type].name);
|
|
@@ -2892,8 +2944,12 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
|
|
out:
|
|
out:
|
|
*p = '\0';
|
|
*p = '\0';
|
|
m->vallen = CAST(unsigned char, (p - origp));
|
|
m->vallen = CAST(unsigned char, (p - origp));
|
|
- if (m->type == FILE_PSTRING)
|
|
|
|
- m->vallen += CAST(unsigned char, file_pstring_length_size(m));
|
|
|
|
|
|
+ if (m->type == FILE_PSTRING) {
|
|
|
|
+ size_t l = file_pstring_length_size(ms, m);
|
|
|
|
+ if (l == FILE_BADSIZE)
|
|
|
|
+ return NULL;
|
|
|
|
+ m->vallen += CAST(unsigned char, l);
|
|
|
|
+ }
|
|
return s;
|
|
return s;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2923,7 +2979,7 @@ file_showstr(FILE *fp, const char *s, size_t len)
|
|
char c;
|
|
char c;
|
|
|
|
|
|
for (;;) {
|
|
for (;;) {
|
|
- if (len == ~0U) {
|
|
|
|
|
|
+ if (len == FILE_BADSIZE) {
|
|
c = *s++;
|
|
c = *s++;
|
|
if (c == '\0')
|
|
if (c == '\0')
|
|
break;
|
|
break;
|
|
@@ -3077,13 +3133,11 @@ apprentice_map(struct magic_set *ms, const char *fn)
|
|
file_badread(ms);
|
|
file_badread(ms);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
-#define RET 1
|
|
|
|
#endif
|
|
#endif
|
|
(void)close(fd);
|
|
(void)close(fd);
|
|
fd = -1;
|
|
fd = -1;
|
|
|
|
|
|
if (check_buffer(ms, map, dbname) != 0) {
|
|
if (check_buffer(ms, map, dbname) != 0) {
|
|
- rv = RCAST(struct magic_map *, -1);
|
|
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
#ifdef QUICK
|
|
#ifdef QUICK
|
|
@@ -3357,7 +3411,7 @@ bs1(struct magic *m)
|
|
}
|
|
}
|
|
|
|
|
|
protected size_t
|
|
protected size_t
|
|
-file_pstring_length_size(const struct magic *m)
|
|
|
|
|
|
+file_pstring_length_size(struct magic_set *ms, const struct magic *m)
|
|
{
|
|
{
|
|
switch (m->str_flags & PSTRING_LEN) {
|
|
switch (m->str_flags & PSTRING_LEN) {
|
|
case PSTRING_1_LE:
|
|
case PSTRING_1_LE:
|
|
@@ -3369,12 +3423,15 @@ file_pstring_length_size(const struct magic *m)
|
|
case PSTRING_4_BE:
|
|
case PSTRING_4_BE:
|
|
return 4;
|
|
return 4;
|
|
default:
|
|
default:
|
|
- abort(); /* Impossible */
|
|
|
|
- return 1;
|
|
|
|
|
|
+ file_error(ms, 0, "corrupt magic file "
|
|
|
|
+ "(bad pascal string length %d)",
|
|
|
|
+ m->str_flags & PSTRING_LEN);
|
|
|
|
+ return FILE_BADSIZE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
protected size_t
|
|
protected size_t
|
|
-file_pstring_get_length(const struct magic *m, const char *ss)
|
|
|
|
|
|
+file_pstring_get_length(struct magic_set *ms, const struct magic *m,
|
|
|
|
+ const char *ss)
|
|
{
|
|
{
|
|
size_t len = 0;
|
|
size_t len = 0;
|
|
const unsigned char *s = RCAST(const unsigned char *, ss);
|
|
const unsigned char *s = RCAST(const unsigned char *, ss);
|
|
@@ -3409,11 +3466,18 @@ file_pstring_get_length(const struct magic *m, const char *ss)
|
|
len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3;
|
|
len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- abort(); /* Impossible */
|
|
|
|
|
|
+ file_error(ms, 0, "corrupt magic file "
|
|
|
|
+ "(bad pascal string length %d)",
|
|
|
|
+ m->str_flags & PSTRING_LEN);
|
|
|
|
+ return FILE_BADSIZE;
|
|
}
|
|
}
|
|
|
|
|
|
- if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF)
|
|
|
|
- len -= file_pstring_length_size(m);
|
|
|
|
|
|
+ if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF) {
|
|
|
|
+ size_t l = file_pstring_length_size(ms, m);
|
|
|
|
+ if (l == FILE_BADSIZE)
|
|
|
|
+ return l;
|
|
|
|
+ len -= l;
|
|
|
|
+ }
|
|
|
|
|
|
return len;
|
|
return len;
|
|
}
|
|
}
|