Sophie

Sophie

distrib > Mageia > 5 > x86_64 > by-pkgid > 1f93505dc591ccc57f1def8beaf6adef > files > 11

file-5.19-10.mga5.src.rpm

https://github.com/file/file/commit/6ce24f35cd4a43c4bdd249e8e0c4952c1f8eac67
https://github.com/file/file/commit/0056ec32255de1de973574b0300161a1568767d6
https://github.com/file/file/commit/09e41625c999a2e5b51e1092f0ef2432a99b5c33
https://github.com/file/file/commit/af444af0738468393f40f9d2261b1ea10fc4b2ba
https://github.com/file/file/commit/68bd8433c7e11a8dbe100deefdfac69138ee7cd9
https://github.com/file/file/commit/dddd3cdb95210a765dd90f7d722cb8b5534daee7
https://github.com/file/file/commit/445c8fb0ebff85195be94cd9f7e1df89cade5c7f
https://github.com/file/file/commit/ce90e05774dd77d86cfc8dfa6da57b32816841c4
https://github.com/file/file/commit/65437cee25199dbd385fb35901bc0011e164276c

diff -urp file-5.19.orig/src/apprentice.c file-5.19/src/apprentice.c
--- file-5.19.orig/src/apprentice.c	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/apprentice.c	2015-01-16 18:49:00.815537942 -0500
@@ -506,7 +506,11 @@ file_ms_alloc(int flags)
 		ms->mlist[i] = NULL;
 	ms->file = "unknown";
 	ms->line = 0;
-	ms->max_recursion = FILE_MAX_RECURSION;
+	ms->indir_max = FILE_INDIR_MAX;
+	ms->name_max = FILE_NAME_MAX;
+	ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
+	ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
+	ms->elf_notes_max = FILE_ELF_NOTES_MAX;
 	return ms;
 free:
 	free(ms);
diff -urp file-5.19.orig/src/ascmagic.c file-5.19/src/ascmagic.c
--- file-5.19.orig/src/ascmagic.c	2014-02-12 18:20:53.000000000 -0500
+++ file-5.19/src/ascmagic.c	2015-01-16 18:47:06.755059966 -0500
@@ -147,7 +147,8 @@ file_ascmagic_with_encoding(struct magic
 		    == NULL)
 			goto done;
 		if ((rv = file_softmagic(ms, utf8_buf,
-		    (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0)
+		    (size_t)(utf8_end - utf8_buf), 0, NULL,
+		    TEXTTEST, text)) == 0)
 			rv = -1;
 	}
 
diff -urp file-5.19.orig/src/elfclass.h file-5.19/src/elfclass.h
--- file-5.19.orig/src/elfclass.h	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/elfclass.h	2015-01-16 18:49:00.815537942 -0500
@@ -32,47 +32,51 @@
 	swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
 
 	type = elf_getu16(swap, elfhdr.e_type);
+	notecount = ms->elf_notes_max;
 	switch (type) {
 #ifdef ELFCORE
 	case ET_CORE:
 		phnum = elf_getu16(swap, elfhdr.e_phnum);
-		if (phnum > MAX_PHNUM)
-			return toomany(ms, "program", phnum);
+		if (phnum > ms->elf_phnum_max)
+			return toomany(ms, "program headers", phnum);
 		flags |= FLAGS_IS_CORE;
 		if (dophn_core(ms, clazz, swap, fd,
 		    (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
 		    (size_t)elf_getu16(swap, elfhdr.e_phentsize),
-		    fsize, &flags) == -1)
+		    fsize, &flags, &notecount) == -1)
 			return -1;
 		break;
 #endif
 	case ET_EXEC:
 	case ET_DYN:
 		phnum = elf_getu16(swap, elfhdr.e_phnum);
-		if (phnum > MAX_PHNUM)
+		if (phnum > ms->elf_phnum_max)
 			return toomany(ms, "program", phnum);
 		shnum = elf_getu16(swap, elfhdr.e_shnum);
-		if (shnum > MAX_SHNUM)
+		if (shnum > ms->elf_shnum_max)
 			return toomany(ms, "section", shnum);
 		if (dophn_exec(ms, clazz, swap, fd,
 		    (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
 		    (size_t)elf_getu16(swap, elfhdr.e_phentsize),
-		    fsize, &flags, shnum) == -1)
+		    fsize, shnum, &flags, &notecount) == -1)
 			return -1;
 		/*FALLTHROUGH*/
 	case ET_REL:
 		shnum = elf_getu16(swap, elfhdr.e_shnum);
-		if (shnum > MAX_SHNUM)
-			return toomany(ms, "section", shnum);
+		if (shnum > ms->elf_shnum_max)
+			return toomany(ms, "section headers", shnum);
 		if (doshn(ms, clazz, swap, fd,
 		    (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
 		    (size_t)elf_getu16(swap, elfhdr.e_shentsize),
-		    fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
-		    (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
+		    fsize, elf_getu16(swap, elfhdr.e_machine),
+		    (int)elf_getu16(swap, elfhdr.e_shstrndx),
+		    &flags, &notecount) == -1)
 			return -1;
 		break;
 
 	default:
 		break;
 	}
+	if (notecount == 0)
+		return toomany(ms, "notes", ms->elf_notes_max);
 	return 1;
diff -urp file-5.19.orig/src/file.c file-5.19/src/file.c
--- file-5.19.orig/src/file.c	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/file.c	2015-01-16 18:49:00.815537942 -0500
@@ -101,7 +101,7 @@ private const struct option long_options
 #undef OPT_LONGONLY
     {0, 0, NULL, 0}
 };
-#define OPTSTRING	"bcCde:Ef:F:hiklLm:nNprR:svz0"
+#define OPTSTRING	"bcCde:Ef:F:hiklLm:nNpP:rsvz0"
 
 private const struct {
 	const char *name;
@@ -119,6 +119,18 @@ private const struct {
 	{ "tokens",	MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */
 };
 
+private struct {
+	const char *name;
+	int tag;
+	size_t value;
+} pm[] = {
+	{ "indir",	MAGIC_PARAM_INDIR_MAX, 0 },
+	{ "name",	MAGIC_PARAM_NAME_MAX, 0 },
+	{ "elf_phnum",	MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
+	{ "elf_shnum",	MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
+	{ "elf_notes",	MAGIC_PARAM_ELF_NOTES_MAX, 0 },
+};
+
 private char *progname;		/* used throughout 		*/
 
 private void usage(void);
@@ -128,6 +140,8 @@ private void help(void);
 private int unwrap(struct magic_set *, const char *);
 private int process(struct magic_set *ms, const char *, int);
 private struct magic_set *load(const char *, int);
+private void setparam(const char *);
+private void applyparam(magic_t);
 
 
 /*
@@ -140,7 +154,6 @@ 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	*/
@@ -244,11 +257,12 @@ main(int argc, char *argv[])
 			flags |= MAGIC_PRESERVE_ATIME;
 			break;
 #endif
+		case 'P':
+			setparam(optarg);
+			break;
 		case 'r':
 			flags |= MAGIC_RAW;
 			break;
-		case 'R':
-			max_recursion = atoi(optarg);
 			break;
 		case 's':
 			flags |= MAGIC_DEVICES;
@@ -327,16 +341,7 @@ 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;
+		applyparam(magic);
 	}
 
 	if (optind == argc) {
@@ -366,6 +371,41 @@ main(int argc, char *argv[])
 	return e;
 }
 
+private void
+applyparam(magic_t magic)
+{
+	size_t i;
+
+	for (i = 0; i < __arraycount(pm); i++) {
+		if (pm[i].value == 0)
+			continue;
+		if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) {
+			(void)fprintf(stderr, "%s: Can't set %s %s\n", progname,
+				pm[i].name, strerror(errno));
+			exit(1);
+		}
+	}
+}
+
+private void
+setparam(const char *p)
+{
+	size_t i;
+	char *s;
+
+	if ((s = strchr(p, '=')) == NULL)
+		goto badparm;
+
+	for (i = 0; i < __arraycount(pm); i++) {
+		if (strncmp(p, pm[i].name, s - p) != 0)
+			continue;
+		pm[i].value = atoi(s + 1);
+		return;
+	}
+badparm:
+	(void)fprintf(stderr, "%s: Unknown param %s\n", progname, p);
+	exit(1);
+}
 
 private struct magic_set *
 /*ARGSUSED*/
diff -urp file-5.19.orig/src/file.h file-5.19/src/file.h
--- file-5.19.orig/src/file.h	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/file.h	2015-01-16 18:49:00.815537942 -0500
@@ -401,8 +401,16 @@ 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
+	uint16_t indir_max;
+	uint16_t name_max;
+	uint16_t elf_shnum_max;
+	uint16_t elf_phnum_max;
+	uint16_t elf_notes_max;
+#define	FILE_INDIR_MAX			15
+#define	FILE_NAME_MAX			30
+#define	FILE_ELF_SHNUM_MAX		32768
+#define	FILE_ELF_PHNUM_MAX		128
+#define	FILE_ELF_NOTES_MAX		256
 };
 
 /* Type for Unicode characters */
@@ -442,7 +450,7 @@ protected int file_encoding(struct magic
     unichar **, size_t *, const char **, const char **, const char **);
 protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
 protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
-    size_t, int, int);
+    uint16_t, uint16_t *, int, int);
 protected int file_apprentice(struct magic_set *, const char *, int);
 protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
 protected uint64_t file_signextend(struct magic_set *, struct magic *,
diff -urp file-5.19.orig/src/file_opts.h file-5.19/src/file_opts.h
--- file-5.19.orig/src/file_opts.h	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/file_opts.h	2015-01-16 18:49:00.815537942 -0500
@@ -43,8 +43,13 @@ OPT('0', "print0", 0, "               te
 #if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
 OPT('p', "preserve-date", 0, "        preserve access times on files\n")
 #endif
+OPT('P', "parameter", 0, "            set file engine parameter limits\n"
+    "                               indir        15 recursion limit for indirection\n"
+    "                               name         30 use limit for name/use magic\n"
+    "                               elf_notes   256 max ELF notes processed\n"
+    "                               elf_phnum   128 max ELF prog sections processed\n"
+    "                               elf_shnum 32768 max ELF sections processed\n")
 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 -urp file-5.19.orig/src/funcs.c file-5.19/src/funcs.c
--- file-5.19.orig/src/funcs.c	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/funcs.c	2015-01-16 18:47:06.755059966 -0500
@@ -230,7 +230,7 @@ file_buffer(struct magic_set *ms, int fd
 
 	/* try soft magic tests */
 	if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
-		if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST,
+		if ((m = file_softmagic(ms, ubuf, nb, 0, NULL, BINTEST,
 		    looks_text)) != 0) {
 			if ((ms->flags & MAGIC_DEBUG) != 0)
 				(void)fprintf(stderr, "softmagic %d\n", m);
diff -urp file-5.19.orig/src/magic.c file-5.19/src/magic.c
--- file-5.19.orig/src/magic.c	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/magic.c	2015-01-16 18:49:00.815537942 -0500
@@ -527,8 +527,20 @@ 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;
+	case MAGIC_PARAM_INDIR_MAX:
+		ms->indir_max = *(const size_t *)val;
+		return 0;
+	case MAGIC_PARAM_NAME_MAX:
+		ms->name_max = *(const size_t *)val;
+		return 0;
+	case MAGIC_PARAM_ELF_PHNUM_MAX:
+		ms->elf_phnum_max = *(const size_t *)val;
+		return 0;
+	case MAGIC_PARAM_ELF_SHNUM_MAX:
+		ms->elf_shnum_max = *(const size_t *)val;
+		return 0;
+	case MAGIC_PARAM_ELF_NOTES_MAX:
+		ms->elf_notes_max = *(const size_t *)val;
 		return 0;
 	default:
 		errno = EINVAL;
@@ -540,8 +552,20 @@ 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;
+	case MAGIC_PARAM_INDIR_MAX:
+		*(size_t *)val = ms->indir_max;
+		return 0;
+	case MAGIC_PARAM_NAME_MAX:
+		*(size_t *)val = ms->name_max;
+		return 0;
+	case MAGIC_PARAM_ELF_PHNUM_MAX:
+		*(size_t *)val = ms->elf_phnum_max;
+		return 0;
+	case MAGIC_PARAM_ELF_SHNUM_MAX:
+		*(size_t *)val = ms->elf_shnum_max;
+		return 0;
+	case MAGIC_PARAM_ELF_NOTES_MAX:
+		*(size_t *)val = ms->elf_notes_max;
 		return 0;
 	default:
 		errno = EINVAL;
diff -urp file-5.19.orig/src/magic.h.in file-5.19/src/magic.h.in
--- file-5.19.orig/src/magic.h.in	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/magic.h.in	2015-01-16 18:49:00.815537942 -0500
@@ -101,7 +101,12 @@ 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
+#define MAGIC_PARAM_INDIR_MAX		0
+#define MAGIC_PARAM_NAME_MAX		1
+#define MAGIC_PARAM_ELF_PHNUM_MAX	2
+#define MAGIC_PARAM_ELF_SHNUM_MAX	3
+#define MAGIC_PARAM_ELF_NOTES_MAX	4
+
 int magic_setparam(magic_t, int, const void *);
 int magic_getparam(magic_t, int, void *);
 
diff -urp file-5.19.orig/src/readelf.c file-5.19/src/readelf.c
--- file-5.19.orig/src/readelf.c	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/readelf.c	2015-01-16 19:03:17.008587246 -0500
@@ -43,14 +43,14 @@ FILE_RCSID("@(#)$File: readelf.c,v 1.103
 
 #ifdef	ELFCORE
 private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
-    off_t, int *);
+    off_t, int *, uint16_t *);
 #endif
 private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
-    off_t, int *, int);
+    off_t, int, int *, uint16_t *);
 private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
-    off_t, int *, int, int);
+    off_t, int, int, int *, uint16_t *);
 private size_t donote(struct magic_set *, void *, size_t, size_t, int,
-    int, size_t, int *);
+    int, size_t, int *, uint16_t *);
 
 #define	ELF_ALIGN(a)	((((a) + align - 1) / align) * align)
 
@@ -62,11 +62,12 @@ private uint64_t getu64(int, uint64_t);
 
 #define MAX_PHNUM	128
 #define	MAX_SHNUM	32768
+#define SIZE_UNKNOWN	((off_t)-1)
 
 private int
 toomany(struct magic_set *ms, const char *name, uint16_t num)
 {
-	if (file_printf(ms, ", too many %s header sections (%u)", name, num
+	if (file_printf(ms, ", too many %s (%u)", name, num
 	    ) == -1)
 		return -1;
 	return 0;
@@ -292,15 +293,19 @@ private const char os_style_names[][8] =
 	"NetBSD",
 };
 
-#define FLAGS_DID_CORE		0x01
-#define FLAGS_DID_NOTE		0x02
-#define FLAGS_DID_BUILD_ID	0x04
-#define FLAGS_DID_CORE_STYLE	0x08
-#define FLAGS_IS_CORE		0x10
+#define FLAGS_DID_CORE			0x001
+#define FLAGS_DID_OS_NOTE		0x002
+#define FLAGS_DID_BUILD_ID		0x004
+#define FLAGS_DID_CORE_STYLE		0x008
+#define FLAGS_DID_NETBSD_PAX		0x010
+#define FLAGS_DID_NETBSD_MARCH		0x020
+#define FLAGS_DID_NETBSD_CMODEL		0x040
+#define FLAGS_DID_NETBSD_UNKNOWN	0x080
+#define FLAGS_IS_CORE			0x100
 
 private int
 dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
-    int num, size_t size, off_t fsize, int *flags)
+    int num, size_t size, off_t fsize, int *flags, uint16_t *notecount)
 {
 	Elf32_Phdr ph32;
 	Elf64_Phdr ph64;
@@ -318,13 +323,13 @@ dophn_core(struct magic_set *ms, int cla
 	 * Loop through all the program headers.
 	 */
 	for ( ; num; num--) {
-		if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
+		if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
 			file_badread(ms);
 			return -1;
 		}
 		off += size;
 
-		if (xph_offset > fsize) {
+		if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
 			/* Perhaps warn here */
 			continue;
 		}
@@ -346,7 +351,7 @@ dophn_core(struct magic_set *ms, int cla
 			if (offset >= (size_t)bufsize)
 				break;
 			offset = donote(ms, nbuf, offset, (size_t)bufsize,
-			    clazz, swap, 4, flags);
+			    clazz, swap, 4, flags, notecount);
 			if (offset == 0)
 				break;
 
@@ -476,132 +481,127 @@ do_note_freebsd_version(struct magic_set
 	}
 }
 
-private size_t
-donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
-    int clazz, int swap, size_t align, int *flags)
+private int
+do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags)
 {
-	Elf32_Nhdr nh32;
-	Elf64_Nhdr nh64;
-	size_t noff, doff;
-#ifdef ELFCORE
-	int os_style = -1;
-#endif
-	uint32_t namesz, descsz;
-	unsigned char *nbuf = CAST(unsigned char *, vbuf);
-
-	if (xnh_sizeof + offset > size) {
-		/*
-		 * We're out of note headers.
-		 */
-		return xnh_sizeof + offset;
-	}
-
-	(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
-	offset += xnh_sizeof;
-
-	namesz = xnh_namesz;
-	descsz = xnh_descsz;
-	if ((namesz == 0) && (descsz == 0)) {
-		/*
-		 * We're out of note headers.
-		 */
-		return (offset >= size) ? offset : size;
-	}
-
-	if (namesz & 0x80000000) {
-	    (void)file_printf(ms, ", bad note name size 0x%lx",
-		(unsigned long)namesz);
-	    return 0;
-	}
-
-	if (descsz & 0x80000000) {
-	    (void)file_printf(ms, ", bad note description size 0x%lx",
-		(unsigned long)descsz);
-	    return 0;
-	}
-
-
-	noff = offset;
-	doff = ELF_ALIGN(offset + namesz);
-
-	if (offset + namesz > size) {
-		/*
-		 * We're past the end of the buffer.
-		 */
-		return doff;
-	}
-
-	offset = ELF_ALIGN(doff + descsz);
-	if (doff + descsz > size) {
-		/*
-		 * We're past the end of the buffer.
-		 */
-		return (offset >= size) ? offset : size;
+	if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+	    type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
+		uint8_t desc[20];
+		uint32_t i;
+		*flags |= FLAGS_DID_BUILD_ID;
+		if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
+		    "sha1") == -1)
+			return 1;
+		(void)memcpy(desc, &nbuf[doff], descsz);
+		for (i = 0; i < descsz; i++)
+		    if (file_printf(ms, "%02x", desc[i]) == -1)
+			return 1;
+		return 1;
 	}
-
-	if ((*flags & (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) ==
-	    (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
-		goto core;
-
+	return 0;
+}
+	
+private int
+do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags)
+{
 	if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
-	    xnh_type == NT_GNU_VERSION && descsz == 2) {
+	    type == NT_GNU_VERSION && descsz == 2) {
+	    *flags |= FLAGS_DID_OS_NOTE;
 	    file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
+	    return 1;
 	}
+
 	if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
-	    xnh_type == NT_GNU_VERSION && descsz == 16) {
+	    type == NT_GNU_VERSION && descsz == 16) {
 		uint32_t desc[4];
 		(void)memcpy(desc, &nbuf[doff], sizeof(desc));
 
+		*flags |= FLAGS_DID_OS_NOTE;
 		if (file_printf(ms, ", for GNU/") == -1)
-			return size;
+			return 1;
 		switch (elf_getu32(swap, desc[0])) {
 		case GNU_OS_LINUX:
 			if (file_printf(ms, "Linux") == -1)
-				return size;
+				return 1;
 			break;
 		case GNU_OS_HURD:
 			if (file_printf(ms, "Hurd") == -1)
-				return size;
+				return 1;
 			break;
 		case GNU_OS_SOLARIS:
 			if (file_printf(ms, "Solaris") == -1)
-				return size;
+				return 1;
 			break;
 		case GNU_OS_KFREEBSD:
 			if (file_printf(ms, "kFreeBSD") == -1)
-				return size;
+				return 1;
 			break;
 		case GNU_OS_KNETBSD:
 			if (file_printf(ms, "kNetBSD") == -1)
-				return size;
+				return 1;
 			break;
 		default:
 			if (file_printf(ms, "<unknown>") == -1)
-				return size; 
+				return 1; 
 		}
 		if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
 		    elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
-			return size;
-		*flags |= FLAGS_DID_NOTE;
-		return size;
+			return 1;
+		return 1;
 	}
 
-	if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
-	    xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
-	    uint8_t desc[20];
-	    uint32_t i;
-	    if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
-		"sha1") == -1)
-		    return size;
-	    (void)memcpy(desc, &nbuf[doff], descsz);
-	    for (i = 0; i < descsz; i++)
-		if (file_printf(ms, "%02x", desc[i]) == -1)
-		    return size;
-	    *flags |= FLAGS_DID_BUILD_ID;
+	if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+	    	if (type == NT_NETBSD_VERSION && descsz == 4) {
+			*flags |= FLAGS_DID_OS_NOTE;
+			do_note_netbsd_version(ms, swap, &nbuf[doff]);
+			return 1;
+		}
+	}
+
+	if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
+	    	if (type == NT_FREEBSD_VERSION && descsz == 4) {
+			*flags |= FLAGS_DID_OS_NOTE;
+			do_note_freebsd_version(ms, swap, &nbuf[doff]);
+			return 1;
+		}
+	}
+
+	if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
+	    type == NT_OPENBSD_VERSION && descsz == 4) {
+		*flags |= FLAGS_DID_OS_NOTE;
+		if (file_printf(ms, ", for OpenBSD") == -1)
+			return 1;
+		/* Content of note is always 0 */
+		return 1;
+	}
+
+	if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
+	    type == NT_DRAGONFLY_VERSION && descsz == 4) {
+		uint32_t desc;
+		*flags |= FLAGS_DID_OS_NOTE;
+		if (file_printf(ms, ", for DragonFly") == -1)
+			return 1;
+		(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
+		desc = elf_getu32(swap, desc);
+		if (file_printf(ms, " %d.%d.%d", desc / 100000,
+		    desc / 10000 % 10, desc % 10000) == -1)
+			return 1;
+		return 1;
 	}
+	return 0;
+}
 
+private int
+do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags)
+{
 	if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
-	    xnh_type == NT_NETBSD_PAX && descsz == 4) {
+	    type == NT_NETBSD_PAX && descsz == 4) {
 		static const char *pax[] = {
 		    "+mprotect",
 		    "-mprotect",
@@ -614,80 +614,32 @@ donote(struct magic_set *ms, void *vbuf,
 		size_t i;
 		int did = 0;
 
+		*flags |= FLAGS_DID_NETBSD_PAX;
 		(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
 		desc = elf_getu32(swap, desc);
 
 		if (desc && file_printf(ms, ", PaX: ") == -1)
-			return size;
+			return 1;
 
 		for (i = 0; i < __arraycount(pax); i++) {
 			if (((1 << i) & desc) == 0)
 				continue;
 			if (file_printf(ms, "%s%s", did++ ? "," : "",
 			    pax[i]) == -1)
-				return size;
-		}
-	}
-
-	if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
-		switch (xnh_type) {
-		case NT_NETBSD_VERSION:
-			if (descsz == 4) {
-				do_note_netbsd_version(ms, swap, &nbuf[doff]);
-				*flags |= FLAGS_DID_NOTE;
-				return size;
-			}
-			break;
-		case NT_NETBSD_MARCH:
-			if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
-			    (const char *)&nbuf[doff]) == -1)
-				return size;
-			break;
-		case NT_NETBSD_CMODEL:
-			if (file_printf(ms, ", compiler model: %.*s",
-			    (int)descsz, (const char *)&nbuf[doff]) == -1)
-				return size;
-			break;
-		default:
-			if (file_printf(ms, ", note=%u", xnh_type) == -1)
-				return size;
-			break;
-		}
-		return size;
-	}
-
-	if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
-	    	if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
-			do_note_freebsd_version(ms, swap, &nbuf[doff]);
-			*flags |= FLAGS_DID_NOTE;
-			return size;
+				return 1;
 		}
+		return 1;
 	}
+	return 0;
+}
 
-	if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
-	    xnh_type == NT_OPENBSD_VERSION && descsz == 4) {
-		if (file_printf(ms, ", for OpenBSD") == -1)
-			return size;
-		/* Content of note is always 0 */
-		*flags |= FLAGS_DID_NOTE;
-		return size;
-	}
-
-	if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
-	    xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
-		uint32_t desc;
-		if (file_printf(ms, ", for DragonFly") == -1)
-			return size;
-		(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
-		desc = elf_getu32(swap, desc);
-		if (file_printf(ms, " %d.%d.%d", desc / 100000,
-		    desc / 10000 % 10, desc % 10000) == -1)
-			return size;
-		*flags |= FLAGS_DID_NOTE;
-		return size;
-	}
-
-core:
+private int
+do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags, size_t size, int clazz)
+{
+#ifdef ELFCORE
+	int os_style = -1;
 	/*
 	 * Sigh.  The 2.0.36 kernel in Debian 2.1, at
 	 * least, doesn't correctly implement name
@@ -716,20 +668,17 @@ core:
 		os_style = OS_STYLE_NETBSD;
 	}
 
-#ifdef ELFCORE
-	if ((*flags & FLAGS_DID_CORE) != 0)
-		return size;
-
 	if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
 		if (file_printf(ms, ", %s-style", os_style_names[os_style])
 		    == -1)
-			return size;
+			return 1;
 		*flags |= FLAGS_DID_CORE_STYLE;
 	}
 
 	switch (os_style) {
 	case OS_STYLE_NETBSD:
-		if (xnh_type == NT_NETBSD_CORE_PROCINFO) {
+		if (type == NT_NETBSD_CORE_PROCINFO) {
+			char sbuf[512];
 			uint32_t signo;
 			/*
 			 * Extract the program name.  It is at
@@ -738,7 +687,7 @@ core:
 			 */
 			if (file_printf(ms, ", from '%.31s'",
 			    &nbuf[doff + 0x7c]) == -1)
-				return size;
+				return 1;
 			
 			/*
 			 * Extract the signal number.  It is at
@@ -748,14 +697,14 @@ core:
 			    sizeof(signo));
 			if (file_printf(ms, " (signal %u)",
 			    elf_getu32(swap, signo)) == -1)
-				return size;
+				return 1;
 			*flags |= FLAGS_DID_CORE;
-			return size;
+			return 1;
 		}
 		break;
 
 	default:
-		if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
+		if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
 			size_t i, j;
 			unsigned char c;
 			/*
@@ -823,7 +772,7 @@ core:
 				 * Try next offsets, in case this match is
 				 * in the middle of a string.
 				 */
-				for (k = i + 1 ; k < NOFFSETS ; k++) {
+				for (k = i + 1 ; k < NOFFSETS; k++) {
 					size_t no;
 					int adjust = 1;
 					if (prpsoffsets(k) >= prpsoffsets(i))
@@ -848,9 +797,9 @@ core:
 					cp--;
 				if (file_printf(ms, ", from '%.*s'",
 				    (int)(cp - cname), cname) == -1)
-					return size;
+					return 1;
 				*flags |= FLAGS_DID_CORE;
-				return size;
+				return 1;
 
 			tryanother:
 				;
@@ -859,6 +808,129 @@ core:
 		break;
 	}
 #endif
+	return 0;
+}
+
+private size_t
+donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
+    int clazz, int swap, size_t align, int *flags, uint16_t *notecount)
+{
+	Elf32_Nhdr nh32;
+	Elf64_Nhdr nh64;
+	size_t noff, doff;
+	uint32_t namesz, descsz;
+	unsigned char *nbuf = CAST(unsigned char *, vbuf);
+
+	if (*notecount == 0)
+		return 0;
+	--*notecount;
+
+	if (xnh_sizeof + offset > size) {
+		/*
+		 * We're out of note headers.
+		 */
+		return xnh_sizeof + offset;
+	}
+
+	(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
+	offset += xnh_sizeof;
+
+	namesz = xnh_namesz;
+	descsz = xnh_descsz;
+	if ((namesz == 0) && (descsz == 0)) {
+		/*
+		 * We're out of note headers.
+		 */
+		return (offset >= size) ? offset : size;
+	}
+
+	if (namesz & 0x80000000) {
+	    (void)file_printf(ms, ", bad note name size 0x%lx",
+		(unsigned long)namesz);
+	    return 0;
+	}
+
+	if (descsz & 0x80000000) {
+	    (void)file_printf(ms, ", bad note description size 0x%lx",
+		(unsigned long)descsz);
+	    return 0;
+	}
+
+	noff = offset;
+	doff = ELF_ALIGN(offset + namesz);
+
+	if (offset + namesz > size) {
+		/*
+		 * We're past the end of the buffer.
+		 */
+		return doff;
+	}
+
+	offset = ELF_ALIGN(doff + descsz);
+	if (doff + descsz > size) {
+		/*
+		 * We're past the end of the buffer.
+		 */
+		return (offset >= size) ? offset : size;
+	}
+
+	if ((*flags & FLAGS_DID_OS_NOTE) == 0) {
+		if (do_os_note(ms, nbuf, xnh_type, swap,
+		    namesz, descsz, noff, doff, flags))
+			return size;
+	}
+
+	if ((*flags & FLAGS_DID_BUILD_ID) == 0) {
+		if (do_bid_note(ms, nbuf, xnh_type, swap,
+		    namesz, descsz, noff, doff, flags))
+			return size;
+	}
+		
+	if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
+		if (do_pax_note(ms, nbuf, xnh_type, swap,
+		    namesz, descsz, noff, doff, flags))
+			return size;
+	}
+
+	if ((*flags & FLAGS_DID_CORE) == 0) {
+		if (do_core_note(ms, nbuf, xnh_type, swap,
+		    namesz, descsz, noff, doff, flags, size, clazz))
+			return size;
+	}
+
+	if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+		if (descsz > 100)
+			descsz = 100;
+		switch (xnh_type) {
+	    	case NT_NETBSD_VERSION:
+			return size;
+		case NT_NETBSD_MARCH:
+			if (*flags & FLAGS_DID_NETBSD_MARCH)
+				return size;
+			*flags |= FLAGS_DID_NETBSD_MARCH;
+			if (file_printf(ms, ", compiled for: %.*s",
+			    (int)descsz, (const char *)&nbuf[doff]) == -1)
+				return size;
+			break;
+		case NT_NETBSD_CMODEL:
+			if (*flags & FLAGS_DID_NETBSD_CMODEL)
+				return size;
+			*flags |= FLAGS_DID_NETBSD_CMODEL;
+			if (file_printf(ms, ", compiler model: %.*s",
+			    (int)descsz, (const char *)&nbuf[doff]) == -1)
+				return size;
+			break;
+		default:
+			if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
+				return size;
+			*flags |= FLAGS_DID_NETBSD_UNKNOWN;
+			if (file_printf(ms, ", note=%u", xnh_type) == -1)
+				return size;
+			break;
+		}
+		return size;
+	}
+
 	return offset;
 }
 
@@ -914,7 +986,8 @@ static const cap_desc_t cap_desc_386[] =
 
 private int
 doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
-    size_t size, off_t fsize, int *flags, int mach, int strtab)
+    size_t size, off_t fsize, int mach, int strtab, int *flags,
+    uint16_t *notecount)
 {
 	Elf32_Shdr sh32;
 	Elf64_Shdr sh64;
@@ -925,6 +998,7 @@ doshn(struct magic_set *ms, int clazz, i
 	uint64_t cap_hw1 = 0;	/* SunOS 5.x hardware capabilites */
 	uint64_t cap_sf1 = 0;	/* SunOS 5.x software capabilites */
 	char name[50];
+	ssize_t namesize;
 
 	if (size != xsh_sizeof) {
 		if (file_printf(ms, ", corrupted section header size") == -1)
@@ -933,7 +1007,7 @@ doshn(struct magic_set *ms, int clazz, i
 	}
 
 	/* Read offset of name section to be able to read section names later */
-	if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) {
+	if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) < (ssize_t)xsh_sizeof) {
 		file_badread(ms);
 		return -1;
 	}
@@ -941,15 +1015,15 @@ doshn(struct magic_set *ms, int clazz, i
 
 	for ( ; num; num--) {
 		/* Read the name of this section. */
-		if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
+		if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) {
 			file_badread(ms);
 			return -1;
 		}
-		name[sizeof(name) - 1] = '\0';
+		name[namesize] = '\0';
 		if (strcmp(name, ".debug_info") == 0)
 			stripped = 0;
 
-		if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
+		if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) {
 			file_badread(ms);
 			return -1;
 		}
@@ -964,7 +1038,7 @@ doshn(struct magic_set *ms, int clazz, i
 			stripped = 0;
 			break;
 		default:
-			if (xsh_offset > fsize) {
+			if (fsize != SIZE_UNKNOWN && xsh_offset > fsize) {
 				/* Perhaps warn here */
 				continue;
 			}
@@ -979,7 +1053,7 @@ doshn(struct magic_set *ms, int clazz, i
 				    " for note");
 				return -1;
 			}
-			if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
+			if (pread(fd, nbuf, xsh_size, xsh_offset) < (ssize_t)xsh_size) {
 				file_badread(ms);
 				free(nbuf);
 				return -1;
@@ -990,7 +1064,7 @@ doshn(struct magic_set *ms, int clazz, i
 				if (noff >= (off_t)xsh_size)
 					break;
 				noff = donote(ms, nbuf, (size_t)noff,
-				    xsh_size, clazz, swap, 4, flags);
+				    xsh_size, clazz, swap, 4, flags, notecount);
 				if (noff == 0)
 					break;
 			}
@@ -1157,7 +1231,8 @@ doshn(struct magic_set *ms, int clazz, i
  */
 private int
 dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
-    int num, size_t size, off_t fsize, int *flags, int sh_num)
+    int num, size_t size, off_t fsize, int sh_num, int *flags,
+    uint16_t *notecount)
 {
 	Elf32_Phdr ph32;
 	Elf64_Phdr ph64;
@@ -1174,7 +1249,7 @@ dophn_exec(struct magic_set *ms, int cla
 	}
 
   	for ( ; num; num--) {
-		if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
+		if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
 			file_badread(ms);
 			return -1;
 		}
@@ -1190,7 +1265,7 @@ dophn_exec(struct magic_set *ms, int cla
 			shared_libraries = " (uses shared libs)";
 			break;
 		default:
-			if (xph_offset > fsize) {
+			if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
 				/* Maybe warn here? */
 				continue;
 			}
@@ -1226,7 +1301,7 @@ dophn_exec(struct magic_set *ms, int cla
 					break;
 				offset = donote(ms, nbuf, offset,
 				    (size_t)bufsize, clazz, swap, align,
-				    flags);
+				    flags, notecount);
 				if (offset == 0)
 					break;
 			}
@@ -1257,7 +1332,7 @@ file_tryelf(struct magic_set *ms, int fd
 	int flags = 0;
 	Elf32_Ehdr elf32hdr;
 	Elf64_Ehdr elf64hdr;
-	uint16_t type, phnum, shnum;
+	uint16_t type, phnum, shnum, notecount;
 
 	if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
 		return 0;
@@ -1283,7 +1358,10 @@ file_tryelf(struct magic_set *ms, int fd
   		file_badread(ms);
 		return -1;
 	}
-	fsize = st.st_size;
+	if (S_ISREG(st.st_mode))
+		fsize = st.st_size;
+	else
+		fsize = SIZE_UNKNOWN;
 
 	clazz = buf[EI_CLASS];
 
diff -urp file-5.19.orig/src/softmagic.c file-5.19/src/softmagic.c
--- file-5.19.orig/src/softmagic.c	2015-01-16 18:00:07.164047330 -0500
+++ file-5.19/src/softmagic.c	2015-01-16 18:48:31.635432702 -0500
@@ -47,11 +47,11 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.1
 
 
 private int match(struct magic_set *, struct magic *, uint32_t,
-    const unsigned char *, size_t, size_t, int, int, int, size_t, int *, int *,
-    int *);
+    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, size_t, int *,
-    int *, int *);
+    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 *);
@@ -75,14 +75,20 @@ private void cvt_64(union VALUETYPE *, c
 /*ARGSUSED1*/		/* nbytes passed for regularity, maybe need later */
 protected int
 file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
-    size_t level, int mode, int text)
+    uint16_t indir_level, uint16_t *name_count, int mode, int text)
 {
 	struct mlist *ml;
 	int rv, printed_something = 0, need_separator = 0;
+	uint16_t nc;
+
+	if (name_count == NULL) {
+		nc = 0;
+		name_count = &nc;
+	}
 	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, level, &printed_something, &need_separator,
-		    NULL)) != 0)
+		    text, 0, indir_level, name_count,
+		    &printed_something, &need_separator, NULL)) != 0)
 			return rv;
 
 	return 0;
@@ -137,8 +143,8 @@ file_fmtcheck(struct magic_set *ms, cons
 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, size_t recursion_level, int *printed_something,
-    int *need_separator, int *returnval)
+    int flip, uint16_t indir_level, uint16_t *name_count,
+    int *printed_something, int *need_separator, int *returnval)
 {
 	uint32_t magindex = 0;
 	unsigned int cont_level = 0;
@@ -175,8 +181,8 @@ match(struct magic_set *ms, struct magic
 
 		/* if main entry matches, print it... */
 		switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
-		    flip, recursion_level + 1, printed_something,
-		    need_separator, returnval)) {
+		    flip, indir_level, name_count,
+		    printed_something, need_separator, returnval)) {
 		case -1:
 			return -1;
 		case 0:
@@ -264,8 +270,8 @@ match(struct magic_set *ms, struct magic
 			}
 #endif
 			switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
-			    text, flip, recursion_level + 1, printed_something,
-			    need_separator, returnval)) {
+			    text, flip, indir_level, name_count,
+			    printed_something, need_separator, returnval)) {
 			case -1:
 				return -1;
 			case 0:
@@ -1194,8 +1200,8 @@ mcopy(struct magic_set *ms, union VALUET
 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, size_t recursion_level, int *printed_something,
-    int *need_separator, int *returnval)
+    int flip, uint16_t indir_level, uint16_t *name_count,
+    int *printed_something, int *need_separator, int *returnval)
 {
 	uint32_t offset = ms->offset;
 	uint32_t lhs;
@@ -1205,9 +1211,15 @@ mget(struct magic_set *ms, const unsigne
 	union VALUETYPE *p = &ms->ms_value;
 	struct mlist ml;
 
-	if (recursion_level >= ms->max_recursion) {
-		file_error(ms, 0, "recursion nesting (%zu) exceeded",
-		    recursion_level);
+	if (indir_level >= ms->indir_max) {
+		file_error(ms, 0, "indirect recursion nesting (%hu) exceeded",
+		    indir_level);
+		return -1;
+	}
+
+	if (*name_count >= ms->name_max) {
+		file_error(ms, 0, "name use count (%hu) exceeded",
+		    *name_count);
 		return -1;
 	}
 
@@ -1217,7 +1229,9 @@ mget(struct magic_set *ms, const unsigne
 
 	if ((ms->flags & MAGIC_DEBUG) != 0) {
 		fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
-		    "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
+		    "nbytes=%zu, il=%hu, nc=%hu)\n",
+		    m->type, m->flag, offset, o, nbytes,
+		    indir_level, *name_count);
 		mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
 #ifndef COMPILE_ONLY
 		file_mdump(m);
@@ -1658,7 +1672,7 @@ mget(struct magic_set *ms, const unsigne
 			return -1;
 
 		rv = file_softmagic(ms, s + offset, nbytes - offset,
-		    recursion_level, BINTEST, text);
+		    indir_level + 1, name_count, BINTEST, text);
 
 		if ((ms->flags & MAGIC_DEBUG) != 0)
 			fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
@@ -1693,13 +1707,13 @@ mget(struct magic_set *ms, const unsigne
 			file_error(ms, 0, "cannot find entry `%s'", rbuf);
 			return -1;
 		}
-
+		(*name_count)++;
 		oneed_separator = *need_separator;
 		if (m->flag & NOSPACE)
 			*need_separator = 0;
 		rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
-		    mode, text, flip, recursion_level, printed_something,
-		    need_separator, returnval);
+		    mode, text, flip, indir_level, name_count,
+		    printed_something, need_separator, returnval);
 		if (rv != 1)
 		    *need_separator = oneed_separator;
 		return rv;