Subject: Bump recursion to 15, and allow it to be set from the command line Upstream-Author: Christos Zoulas Date: Thu Nov 27 15:40:36 2014 +0000 Origin: FILE5_20-34-g90018fe Last-Update: 2015-01-05 diff --git a/src/file.c b/src/file.c index 408ec63..2f3cf9d 100644 --- a/src/file.c +++ b/src/file.c @@ -101,7 +101,7 @@ private const struct option long_options[] = { #undef OPT_LONGONLY {0, 0, NULL, 0} }; -#define OPTSTRING "bcCde:f:F:hiklLm:nNprsvz0" +#define OPTSTRING "bcCde:f:F:hiklLm:nNprR:svz0" private const struct { const char *name; @@ -140,6 +140,7 @@ main(int argc, char *argv[]) size_t i; int action = 0, didsomefiles = 0, errflg = 0; int flags = 0, e = 0; + size_t max_recursion = 0; struct magic_set *magic = NULL; int longindex; const char *magicfile = NULL; /* where the magic is */ @@ -243,6 +244,9 @@ main(int argc, char *argv[]) case 'r': flags |= MAGIC_RAW; break; + case 'R': + max_recursion = atoi(optarg); + break; case 's': flags |= MAGIC_DEVICES; break; @@ -290,6 +294,8 @@ main(int argc, char *argv[]) strerror(errno)); return 1; } + + switch(action) { case FILE_CHECK: c = magic_check(magic, magicfile); @@ -313,6 +319,15 @@ main(int argc, char *argv[]) if (magic == NULL) if ((magic = load(magicfile, flags)) == NULL) return 1; + if (max_recursion) { + if (magic_setparam(magic, MAGIC_PARAM_MAX_RECURSION, + &max_recursion) == -1) { + (void)fprintf(stderr, + "%s: Can't set recurision %s\n", progname, + strerror(errno)); + return 1; + } + } break; } diff --git a/src/file.h b/src/file.h index 6f61643..71a3aeb 100644 --- a/src/file.h +++ b/src/file.h @@ -380,6 +380,8 @@ struct magic_set { /* FIXME: Make the string dynamically allocated so that e.g. strings matched in files can be longer than MAXstring */ union VALUETYPE ms_value; /* either number or string */ + size_t max_recursion; +#define FILE_MAX_RECURSION 15 }; /* Type for Unicode characters */ diff --git a/src/file_opts.h b/src/file_opts.h index 8a17672..4245447 100644 --- a/src/file_opts.h +++ b/src/file_opts.h @@ -44,6 +44,7 @@ OPT('0', "print0", 0, " terminate filenames with ASCII NUL\n") OPT('p', "preserve-date", 0, " preserve access times on files\n") #endif OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n") +OPT('R', "recursion", 0, " set maximum recursion level\n") OPT('s', "special-files", 0, " treat special (block/char devices) files as\n" " ordinary ones\n") OPT('C', "compile", 0, " compile file specified by -m\n") diff --git a/src/magic.c b/src/magic.c index 5403951..2a916c7 100644 --- a/src/magic.c +++ b/src/magic.c @@ -233,6 +233,7 @@ magic_open(int flags) ms->mlist = NULL; ms->file = "unknown"; ms->line = 0; + ms->max_recursion = FILE_MAX_RECURSION; return ms; free: free(ms); @@ -511,3 +512,29 @@ magic_setflags(struct magic_set *ms, int flags) ms->flags = flags; return 0; } + +public int +magic_setparam(struct magic_set *ms, int param, const void *val) +{ + switch (param) { + case MAGIC_PARAM_MAX_RECURSION: + ms->max_recursion = *(const size_t *)val; + return 0; + default: + errno = EINVAL; + return -1; + } +} + +public int +magic_getparam(struct magic_set *ms, int param, void *val) +{ + switch (param) { + case MAGIC_PARAM_MAX_RECURSION: + *(size_t *)val = ms->max_recursion; + return 0; + default: + errno = EINVAL; + return -1; + } +} diff --git a/src/magic.h b/src/magic.h index 2bbed76..3d9ee8a 100644 --- a/src/magic.h +++ b/src/magic.h @@ -92,11 +92,17 @@ const char *magic_error(magic_t); int magic_setflags(magic_t, int); int magic_load(magic_t, const char *); +int magic_load_buffers(magic_t, void **, size_t *, size_t); + int magic_compile(magic_t, const char *); int magic_check(magic_t, const char *); int magic_list(magic_t, const char *); int magic_errno(magic_t); +#define MAGIC_PARAM_MAX_RECURSION 0 +int magic_setparam(magic_t, int, const void *); +int magic_getparam(magic_t, int, void *); + #ifdef __cplusplus }; #endif diff --git a/src/softmagic.c b/src/softmagic.c index 0ace99f..188e66b 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -43,9 +43,9 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.147 2011/11/05 15:44:22 rrt Exp $") private int match(struct magic_set *, struct magic *, uint32_t, - const unsigned char *, size_t, int, int, int); + const unsigned char *, size_t, int, int, size_t); private int mget(struct magic_set *, const unsigned char *, - struct magic *, size_t, unsigned int, int, int); + struct magic *, size_t, unsigned int, int, size_t); 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 *); @@ -62,8 +62,6 @@ private void cvt_64(union VALUETYPE *, const struct magic *); #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) -#define MAX_RECURSION_LEVEL 10 - /* * softmagic - lookup one file in parsed, in-memory copy of database * Passed the name and FILE * of one file to be typed. @@ -113,7 +111,7 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, private int match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, const unsigned char *s, size_t nbytes, int mode, int text, - int recursion_level) + size_t recursion_level) { uint32_t magindex = 0; unsigned int cont_level = 0; @@ -1044,7 +1042,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, private int mget(struct magic_set *ms, const unsigned char *s, struct magic *m, size_t nbytes, unsigned int cont_level, int text, - int recursion_level) + size_t recursion_level) { uint32_t offset = ms->offset; file_pushbuf_t *pb; @@ -1052,10 +1050,11 @@ mget(struct magic_set *ms, const unsigned char *s, char *rbuf; union VALUETYPE *p = &ms->ms_value; - if (recursion_level >= MAX_RECURSION_LEVEL) { - file_error(ms, 0, "recursion nesting exceeded"); - return -1; - } + if (recursion_level >= ms->max_recursion) { + file_error(ms, 0, "recursion nesting (%zu) exceeded", + recursion_level); + return -1; + } if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, (uint32_t)nbytes, m) == -1)