#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.181 2013/01/03 23:11:38 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.182 2013/01/06 20:36:18 christos Exp $")
#endif /* lint */
#include "magic.h"
private uint32_t swap4(uint32_t);
private uint64_t swap8(uint64_t);
private char *mkdbname(struct magic_set *, const char *, int);
+private void delmagic(struct magic *, int, size_t, size_t);
private int apprentice_map(struct magic_set *, struct magic **, uint32_t *,
const char *);
private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *,
}
private int
-add_mlist(struct mlist *mlp, struct magic *magic, uint32_t nmagic, int mapped)
+add_mlist(struct mlist *mlp, struct magic *magic, uint32_t nmagic, int mapped,
+ size_t idx)
{
struct mlist *ml;
ml->magic = magic;
ml->nmagic = nmagic;
ml->mapped = mapped;
+ ml->idx = idx;
mlp->prev->next = ml;
ml->prev = mlp->prev;
for (i = 0; i < MAGIC_SETS; i++) {
if (magic[i] == NULL)
continue;
- if (add_mlist(ms->mlist[i], magic[i], nmagic[i], mapped) == -1)
- {
+ if (add_mlist(ms->mlist[i], magic[i], nmagic[i], mapped, i) == -1) {
i = i == 1 ? 0 : 1;
- file_delmagic(magic[i], mapped, nmagic[i]);
+ delmagic(magic[i], mapped, nmagic[i], i);
file_oomem(ms, sizeof(*ml));
return -1;
}
return NULL;
}
-protected void
-file_delmagic(struct magic *p, int type, size_t entries)
+private void
+delmagic(struct magic *p, int type, size_t entries, size_t idx)
{
if (p == NULL)
return;
switch (type) {
case 2:
#ifdef QUICK
- p--;
- (void)munmap((void *)p, sizeof(*p) * (entries + 1));
+ /*
+ * if we are mmapped, for the first chunk is one after the header
+ * so we subtract one to get to the header and add one to the
+ * entries to compensate.
+ */
+ if (idx == 0)
+ p--;
+ (void)munmap((void *)p, sizeof(*p) * (entries + (idx == 0)));
break;
#else
(void)&entries;
/*NOTREACHED*/
#endif
case 1:
- p--;
- /*FALLTHROUGH*/
+ /*
+ * If we are allocated only the first block is allocated, the
+ * rest are offsets in the first allocation block. Again, we
+ * compensate for the header.
+ */
+ if (idx == 0)
+ free(--p);
+ break;
case 0:
- free(p);
break;
default:
abort();
mlist_alloc(void)
{
struct mlist *mlist;
- if ((mlist = CAST(struct mlist *, malloc(sizeof(*mlist)))) == NULL) {
+ if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
return NULL;
}
mlist->next = mlist->prev = mlist;
for (ml = mlist->next; ml != mlist;) {
struct mlist *next = ml->next;
struct magic *mg = ml->magic;
- file_delmagic(mg, ml->mapped, ml->nmagic);
+ delmagic(mg, ml->mapped, ml->nmagic, ml->idx);
free(ml);
ml = next;
}
q++;
/* Compatibility with old code that looked in .mime */
if (ms->flags & MAGIC_MIME) {
- asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext);
+ if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
+ return NULL;
if (access(buf, R_OK) != -1) {
ms->flags &= MAGIC_MIME_TYPE;
return buf;
}
free(buf);
}
- asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext);
+ if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
+ return NULL;
/* Compatibility with old code that looked in .mime */
if (strstr(p, ".mime") != NULL)
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.139 2012/09/06 14:42:39 christos Exp $
+ * @(#)$File: file.h,v 1.140 2012/10/30 23:11:51 christos Exp $
*/
#ifndef __file_h__
/* list of magic entries */
struct mlist {
struct magic *magic; /* array of magic entries */
- uint32_t nmagic; /* number of entries in array */
+ uint32_t nmagic; /* number of entries in array */
int mapped; /* allocation type: 0 => apprentice_file
* 1 => apprentice_map + malloc
* 2 => apprentice_map + mmap */
+ size_t idx; /* index in the mapping array */
struct mlist *next, *prev;
};
protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
protected uint64_t file_signextend(struct magic_set *, struct magic *,
uint64_t);
-protected void file_delmagic(struct magic *, int type, size_t entries);
protected void file_badread(struct magic_set *);
protected void file_badseek(struct magic_set *);
protected void file_oomem(struct magic_set *, size_t);