mvadkert / rpms / file

Forked from rpms/file 5 years ago
Clone
Blob Blame History Raw
From 1198be74dcd8982dfcc9ba5a05e8950376ea74af Mon Sep 17 00:00:00 2001
From: Christos Zoulas <christos@zoulas.com>
Date: Thu, 2 May 2013 21:58:20 +0000
Subject: [PATCH] PR/248: Multiple magic_loads fail due to global address
 re-use. Add a struct to describe the set entries eliminating the global
 variable.

---
 src/apprentice.c | 58 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 32 insertions(+), 26 deletions(-)

diff --git a/src/apprentice.c b/src/apprentice.c
index 32ba2c0..aca977d 100644
--- a/src/apprentice.c
+++ b/src/apprentice.c
@@ -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;
@@ -125,7 +131,6 @@ private int apprentice_compile(struct magic_set *, struct magic_map *,
 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";
@@ -897,24 +902,24 @@ struct type_tbl_s {
 
 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;
 }
@@ -924,7 +929,7 @@ struct type_tbl_s {
  */
 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;
@@ -991,7 +996,7 @@ struct type_tbl_s {
 			case 0:
 				continue;
 			case 1:
-				(void)addentry(ms, &me, mentry, mentrycount);
+				(void)addentry(ms, &me, mset);
 				goto again;
 			default:
 				(*errs)++;
@@ -1000,7 +1005,7 @@ struct type_tbl_s {
 		}
 	}
 	if (me.mp)
-		(void)addentry(ms, &me, mentry, mentrycount);
+		(void)addentry(ms, &me, mset);
 	free(line);
 	(void)fclose(f);
 }
@@ -1111,19 +1116,21 @@ struct type_tbl_s {
 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;
 	}
@@ -1169,36 +1176,35 @@ struct type_tbl_s {
 		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;
@@ -1207,7 +1213,7 @@ struct type_tbl_s {
 
 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++) {
-- 
1.8.4