Skip to content

Commit

Permalink
PR/248: Multiple magic_loads fail due to global address re-use. Add a…
Browse files Browse the repository at this point in the history
… struct

to describe the set entries eliminating the global variable.
  • Loading branch information
zoulasc committed May 2, 2013
1 parent 9edd711 commit 1198be7
Showing 1 changed file with 32 additions and 26 deletions.
58 changes: 32 additions & 26 deletions src/apprentice.c
Expand Up @@ -32,7 +32,7 @@
#include "file.h"

#ifndef lint
FILE_RCSID("@(#)$File: apprentice.c,v 1.192 2013/03/25 17:20:43 christos Exp $")
FILE_RCSID("@(#)$File: apprentice.c,v 1.193 2013/04/22 15:30:11 christos Exp $")
#endif /* lint */

#include "magic.h"
Expand Down Expand Up @@ -80,6 +80,12 @@ struct magic_entry {
uint32_t max_count;
};

struct magic_entry_set {
struct magic_entry *me;
uint32_t count;
uint32_t max;
};

struct magic_map {
void *p;
size_t len;
Expand Down Expand Up @@ -125,7 +131,6 @@ 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 size_t maxmagic[MAGIC_SETS] = { 0 };
private size_t magicsize = sizeof(struct magic);

private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
Expand Down Expand Up @@ -897,24 +902,24 @@ set_test_type(struct magic *mstart, struct magic *m)

private int
addentry(struct magic_set *ms, struct magic_entry *me,
struct magic_entry **mentry, uint32_t *mentrycount)
struct magic_entry_set *mset)
{
size_t i = me->mp->type == FILE_NAME ? 1 : 0;
if (mentrycount[i] == maxmagic[i]) {
if (mset[i].count == mset[i].max) {
struct magic_entry *mp;

maxmagic[i] += ALLOC_INCR;
mset[i].max += ALLOC_INCR;
if ((mp = CAST(struct magic_entry *,
realloc(mentry[i], sizeof(*mp) * maxmagic[i]))) ==
realloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
NULL) {
file_oomem(ms, sizeof(*mp) * maxmagic[i]);
file_oomem(ms, sizeof(*mp) * mset[i].max);
return -1;
}
(void)memset(&mp[mentrycount[i]], 0, sizeof(*mp) *
(void)memset(&mp[mset[i].count], 0, sizeof(*mp) *
ALLOC_INCR);
mentry[i] = mp;
mset[i].me = mp;
}
mentry[i][mentrycount[i]++] = *me;
mset[i].me[mset[i].count++] = *me;
memset(me, 0, sizeof(*me));
return 0;
}
Expand All @@ -924,7 +929,7 @@ addentry(struct magic_set *ms, struct magic_entry *me,
*/
private void
load_1(struct magic_set *ms, int action, const char *fn, int *errs,
struct magic_entry **mentry, uint32_t *mentrycount)
struct magic_entry_set *mset)
{
size_t lineno = 0, llen = 0;
char *line = NULL;
Expand Down Expand Up @@ -991,7 +996,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
case 0:
continue;
case 1:
(void)addentry(ms, &me, mentry, mentrycount);
(void)addentry(ms, &me, mset);
goto again;
default:
(*errs)++;
Expand All @@ -1000,7 +1005,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
}
}
if (me.mp)
(void)addentry(ms, &me, mentry, mentrycount);
(void)addentry(ms, &me, mset);
free(line);
(void)fclose(f);
}
Expand Down Expand Up @@ -1111,19 +1116,21 @@ private struct magic_map *
apprentice_load(struct magic_set *ms, const char *fn, int action)
{
int errs = 0;
struct magic_entry *mentry[MAGIC_SETS] = { NULL };
uint32_t mentrycount[MAGIC_SETS] = { 0 };
uint32_t i, j;
size_t files = 0, maxfiles = 0;
char **filearr = NULL, *mfn;
struct stat st;
struct magic_map *map;
struct magic_entry_set mset[MAGIC_SETS];
DIR *dir;
struct dirent *d;

memset(mset, 0, sizeof(mset));
ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */

if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {

if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL)
{
file_oomem(ms, sizeof(*map));
return NULL;
}
Expand Down Expand Up @@ -1169,36 +1176,35 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
closedir(dir);
qsort(filearr, files, sizeof(*filearr), cmpstrp);
for (i = 0; i < files; i++) {
load_1(ms, action, filearr[i], &errs, mentry,
mentrycount);
load_1(ms, action, filearr[i], &errs, mset);
free(filearr[i]);
}
free(filearr);
} else
load_1(ms, action, fn, &errs, mentry, mentrycount);
load_1(ms, action, fn, &errs, mset);
if (errs)
goto out;

for (j = 0; j < MAGIC_SETS; j++) {
/* Set types of tests */
for (i = 0; i < mentrycount[j]; ) {
if (mentry[j][i].mp->cont_level != 0) {
for (i = 0; i < mset[j].count; ) {
if (mset[j].me[i].mp->cont_level != 0) {
i++;
continue;
}
i = set_text_binary(ms, mentry[j], mentrycount[j], i);
i = set_text_binary(ms, mset[j].me, mset[j].count, i);
}
qsort(mentry[j], mentrycount[j], sizeof(*mentry[j]),
qsort(mset[j].me, mset[j].count, sizeof(*mset[j].me),
apprentice_sort);

/*
* Make sure that any level 0 "default" line is last
* (if one exists).
*/
set_last_default(ms, mentry[j], mentrycount[j]);
set_last_default(ms, mset[j].me, mset[j].count);

/* coalesce per file arrays into a single one */
if (coalesce_entries(ms, mentry[j], mentrycount[j],
if (coalesce_entries(ms, mset[j].me, mset[j].count,
&map->magic[j], &map->nmagic[j]) == -1) {
errs++;
goto out;
Expand All @@ -1207,7 +1213,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)

out:
for (j = 0; j < MAGIC_SETS; j++)
magic_entry_free(mentry[j], mentrycount[j]);
magic_entry_free(mset[j].me, mset[j].count);

if (errs) {
for (j = 0; j < MAGIC_SETS; j++) {
Expand Down

0 comments on commit 1198be7

Please sign in to comment.