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;

Reply via email to