Now thinking again I see no much point in my diff, I prefer yours as it's easier to update to a newer file(1), no point in changing only this.
ok from me. On Wed, Sep 28, 2011 at 12:33:13AM -0300, Christiano F. Haesbaert wrote: > On Thu, Sep 22, 2011 at 03:56:11PM +0100, Edd Barrett wrote: > > Hi, > > > > An upstream of one of the ports I work on (radare2) has imported our file(1) > > implementation and claims to have found bugs. This is the first: > > > > 'ms->file' will only be assigned to 'fn' after a call to apprentice_load() > > and > > ultimately load_1(), so the file_magwarn() at line 274 would report the > > default > > filename "unknown". > > > > We can trigger this behaviour by executing `file -c`: > > unknown, 0: Warning: using regular magic file `/etc/magic' > > > > Is it a bug? > > > > Index: apprentice.c > > =================================================================== > > RCS file: /cvs/src/usr.bin/file/apprentice.c,v > > retrieving revision 1.29 > > diff -u -r1.29 apprentice.c > > --- apprentice.c 11 Nov 2009 16:21:51 -0000 1.29 > > +++ apprentice.c 22 Sep 2011 14:27:17 -0000 > > @@ -258,6 +258,7 @@ > > return -1; > > } > > > > + ms->file = fn; > > if (action == FILE_COMPILE) { > > rv = apprentice_load(ms, &magic, &nmagic, fn, action); > > if (rv != 0) > > Seems correct to me, but this "fn" seems kinda redundant down the > stack, except for load_1() which really needs a file and not a > directory. > > So I thought we could kill this fn by assigning ms->file right in the > beginning at file_apprentice(). Also tweak load_1() so it won't do the > whole processing in an else. > > Index: apprentice.c > =================================================================== > RCS file: /cvs/src/usr.bin/file/apprentice.c,v > retrieving revision 1.29 > diff -d -u -p -w -r1.29 apprentice.c > --- apprentice.c 11 Nov 2009 16:21:51 -0000 1.29 > +++ apprentice.c 28 Sep 2011 03:18:29 -0000 > @@ -96,11 +96,11 @@ private int parse(struct magic_set *, st > private int parse_mime(struct magic_set *, struct magic_entry **, uint32_t *, > const char *); > private void eatsize(const char **); > -private int apprentice_1(struct magic_set *, const char *, int, struct mlist > *); > +private int apprentice_1(struct magic_set *, int, struct mlist *); > private size_t apprentice_magic_strength(const struct magic *); > private int apprentice_sort(const void *, const void *); > private int apprentice_load(struct magic_set *, struct magic **, uint32_t *, > - const char *, int); > + int); > private void byteswap(struct magic *, uint32_t); > private void bs1(struct magic *); > private uint16_t swap2(uint16_t); > @@ -242,7 +242,7 @@ init_file_tables(void) > * Handle one file or directory. > */ > private int > -apprentice_1(struct magic_set *ms, const char *fn, int action, > +apprentice_1(struct magic_set *ms, int action, > struct mlist *mlist) > { > struct magic *magic = NULL; > @@ -259,19 +259,19 @@ apprentice_1(struct magic_set *ms, const > } > > if (action == FILE_COMPILE) { > - rv = apprentice_load(ms, &magic, &nmagic, fn, action); > + rv = apprentice_load(ms, &magic, &nmagic, action); > if (rv != 0) > return -1; > - rv = apprentice_compile(ms, &magic, &nmagic, fn); > + rv = apprentice_compile(ms, &magic, &nmagic, ms->file); > free(magic); > return rv; > } > > #ifndef COMPILE_ONLY > - if ((rv = apprentice_map(ms, &magic, &nmagic, fn)) == -1) { > + if ((rv = apprentice_map(ms, &magic, &nmagic, ms->file)) == -1) { > if (ms->flags & MAGIC_CHECK) > - file_magwarn(ms, "using regular magic file `%s'", fn); > - rv = apprentice_load(ms, &magic, &nmagic, fn, action); > + file_magwarn(ms, "using regular magic file `%s'", > ms->file); > + rv = apprentice_load(ms, &magic, &nmagic, action); > if (rv != 0) > return -1; > } > @@ -359,7 +359,8 @@ file_apprentice(struct magic_set *ms, co > *p++ = '\0'; > if (*fn == '\0') > break; > - file_err = apprentice_1(ms, fn, action, mlist); > + ms->file = fn; > + file_err = apprentice_1(ms, action, mlist); > errs = MAX(errs, file_err); > fn = p; > } > @@ -571,13 +572,15 @@ load_1(struct magic_set *ms, int action, > { > char line[BUFSIZ]; > size_t lineno = 0; > - FILE *f = fopen(ms->file = fn, "r"); > - if (f == NULL) { > + FILE *f; > + > + if ((f = fopen(fn, "r")) == NULL) { > if (errno != ENOENT) > file_error(ms, errno, "cannot read magic file `%s'", > fn); > (*errs)++; > - } else { > + return; > + } > /* read and parse this file */ > for (ms->line = 1; fgets(line, sizeof(line), f) != NULL; > ms->line++) { > size_t len; > @@ -606,7 +609,6 @@ load_1(struct magic_set *ms, int action, > > (void)fclose(f); > } > -} > > /* > * parse a file or directory of files > @@ -614,7 +616,7 @@ load_1(struct magic_set *ms, int action, > */ > private int > apprentice_load(struct magic_set *ms, struct magic **magicp, uint32_t > *nmagicp, > - const char *fn, int action) > + int action) > { > int errs = 0; > struct magic_entry *marray; > @@ -625,7 +627,6 @@ apprentice_load(struct magic_set *ms, st > struct dirent *d; > > ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */ > - > maxmagic = MAXMAGIS; > if ((marray = calloc(maxmagic, sizeof(*marray))) == NULL) { > file_oomem(ms, maxmagic * sizeof(*marray)); > @@ -638,12 +639,12 @@ apprentice_load(struct magic_set *ms, st > (void)fprintf(stderr, "%s\n", usg_hdr); > > /* load directory or file */ > - if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) { > - dir = opendir(fn); > + if (stat(ms->file, &st) == 0 && S_ISDIR(st.st_mode)) { > + dir = opendir(ms->file); > if (dir) { > while (d = readdir(dir)) { > snprintf(subfn, sizeof(subfn), "%s/%s", > - fn, d->d_name); > + ms->file, d->d_name); > if (stat(subfn, &st) == 0 && > S_ISREG(st.st_mode)) { > load_1(ms, action, subfn, &errs, > &marray, &marraycount); > @@ -653,7 +654,7 @@ apprentice_load(struct magic_set *ms, st > } else > errs++; > } else > - load_1(ms, action, fn, &errs, &marray, &marraycount); > + load_1(ms, action, ms->file, &errs, &marray, &marraycount); > if (errs) > goto out;