]> granicus.if.org Git - file/commitdiff
- store print the line number of the magic entry for debugging.
authorChristos Zoulas <christos@zoulas.com>
Fri, 8 Dec 2006 20:31:07 +0000 (20:31 +0000)
committerChristos Zoulas <christos@zoulas.com>
Fri, 8 Dec 2006 20:31:07 +0000 (20:31 +0000)
- if the magic entry did not print anything, don't treat it as a match
- change the magic strength algorithm to take into account the relationship op.

src/apprentice.c
src/file.h
src/print.c
src/softmagic.c

index 9f801dbb2395a7cae35977833ceba3733346db9f..0ca23263ca43509c95577387272133c60e62cd34 100644 (file)
@@ -46,7 +46,7 @@
 #endif
 
 #ifndef        lint
-FILE_RCSID("@(#)$Id: apprentice.c,v 1.98 2006/10/31 19:37:17 christos Exp $")
+FILE_RCSID("@(#)$Id: apprentice.c,v 1.99 2006/12/08 20:31:07 christos Exp $")
 #endif /* lint */
 
 #define        EATAB {while (isascii((unsigned char) *l) && \
@@ -97,7 +97,7 @@ private int hextoint(int);
 private const char *getstr(struct magic_set *, const char *, char *, int,
     int *);
 private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
-    const char *, int);
+    const char *, size_t, int);
 private void eatsize(const char **);
 private int apprentice_1(struct magic_set *, const char *, int, struct mlist *);
 private size_t apprentice_magic_strength(const struct magic *);
@@ -312,33 +312,40 @@ private size_t
 apprentice_magic_strength(const struct magic *m)
 {
 #define MULT 10
+       size_t val = 2 * MULT;  /* baseline strength */
 
        switch (m->type) {
        case FILE_BYTE:
-               return 1 * MULT;
+               val += 1 * MULT;
+               break;
 
        case FILE_SHORT:
        case FILE_LESHORT:
        case FILE_BESHORT:
-               return 2 * MULT;
+               val += 2 * MULT;
+               break;
 
        case FILE_LONG:
        case FILE_LELONG:
        case FILE_BELONG:
        case FILE_MELONG:
-               return 4 * MULT;
+               val += 4 * MULT;
+               break;
 
        case FILE_PSTRING:
        case FILE_STRING:
-               return m->vallen * MULT;
+               val += m->vallen * MULT;
+               break;
 
        case FILE_BESTRING16:
        case FILE_LESTRING16:
-               return m->vallen * MULT / 2;
+               val += m->vallen * MULT / 2;
+               break;
 
        case FILE_SEARCH:
        case FILE_REGEX:
-               return m->vallen;
+               val += m->vallen;
+               break;
 
        case FILE_DATE:
        case FILE_LEDATE:
@@ -348,7 +355,8 @@ apprentice_magic_strength(const struct magic *m)
        case FILE_LELDATE:
        case FILE_BELDATE:
        case FILE_MELDATE:
-               return 4 * MULT;
+               val += 4 * MULT;
+               break;
 
        case FILE_QDATE:
        case FILE_LEQDATE:
@@ -356,11 +364,40 @@ apprentice_magic_strength(const struct magic *m)
        case FILE_QLDATE:
        case FILE_LEQLDATE:
        case FILE_BEQLDATE:
-               return 8 * MULT;
+               val += 8 * MULT;
+               break;
 
        default:
-               return 0;
+               val = 0;
+               (void)fprintf(stderr, "Bad type %d\n", m->type);
+               abort();
+       }
+
+       switch (m->reln) {
+       case 'x':       /* matches anything penalize */
+               val = 0;
+               break;
+
+       case '!':
+       case '=':       /* Exact match, prefer */
+               val += MULT;
+               break;
+
+       case '>':
+       case '<':       /* comparison match reduce strength */
+               val -= 2 * MULT;
+               break;
+
+       case '^':
+       case '&':       /* masking bits, we could count them too */
+               val -= MULT;
+               break;
+
+       default:
+               (void)fprintf(stderr, "Bad relation %c\n", m->reln);
+               abort();
        }
+       return val;
 }
 
 /*  
@@ -396,6 +433,7 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
        int errs = 0;
        struct magic_entry *marray;
        uint32_t marraycount, i, mentrycount = 0;
+       size_t lineno = 0;
 
        ms->flags |= MAGIC_CHECK;       /* Enable checks for parsed files */
 
@@ -422,14 +460,18 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
        /* read and parse this file */
        for (ms->line = 1; fgets(line, BUFSIZ, f) != NULL; ms->line++) {
                size_t len;
-               if (line[0] == '#')     /* comment, do not parse */
-                       continue;
                len = strlen(line);
-               if (len < 2) /* null line, garbage, etc */
+               if (len == 0) /* null line, garbage, etc */
                        continue;
-               if (line[len - 1] == '\n')
+               if (line[len - 1] == '\n') {
+                       lineno++;
                        line[len - 1] = '\0'; /* delete newline */
-               if (parse(ms, &marray, &marraycount, line, action) != 0)
+               }
+               if (line[0] == '\0')    /* empty, do not parse */
+                       continue;
+               if (line[0] == '#')     /* comment, do not parse */
+                       continue;
+               if (parse(ms, &marray, &marraycount, line, lineno, action) != 0)
                        errs++;
        }
 
@@ -538,7 +580,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
  */
 private int
 parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp, 
-    const char *line, int action)
+    const char *line, size_t lineno, int action)
 {
        size_t i;
        struct magic_entry *me;
@@ -606,6 +648,7 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
                m->cont_level = 0;
                me->cont_count = 1;
        }
+       m->lineno = lineno;
 
        if (m->cont_level != 0 && *l == '&') {
                 ++l;            /* step over */
index 0e42caae20a6c73177a0d2539b8439b85cb72388..d223d5c20dafe3827d4e04675728d2fa91802009 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.81 2006/11/25 17:28:54 christos Exp $
+ * @(#)$Id: file.h,v 1.82 2006/12/08 20:31:07 christos Exp $
  */
 
 #ifndef __file_h__
@@ -225,7 +225,7 @@ struct magic {
        /* Word 5 */
        int32_t in_offset;      /* offset from indirection */
        /* Word 6 */
-       uint32_t dummy4;
+       uint32_t lineno;        /* line number in magic file */
        /* Word 7,8 */
        uint64_t mask;  /* mask before comparison with value */
        /* Words 9-16 */
index 960469226f99f421ccebe6ec9842c341fbdb70e9..28cca18cbc093e6b5fcc89983feb5eb5f18800c9 100644 (file)
@@ -41,7 +41,7 @@
 #include <time.h>
 
 #ifndef lint
-FILE_RCSID("@(#)$Id: print.c,v 1.55 2006/11/01 20:16:43 christos Exp $")
+FILE_RCSID("@(#)$Id: print.c,v 1.56 2006/12/08 20:31:07 christos Exp $")
 #endif  /* lint */
 
 #define SZOF(a)        (sizeof(a) / sizeof(a[0]))
@@ -52,7 +52,7 @@ file_mdump(struct magic *m)
 {
        private const char optyp[] = { FILE_OPS };
 
-       (void) fputc('[', stderr);
+       (void) fprintf(stderr, "[%zu", m->lineno);
        (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
                       m->offset);
 
index 72f07840ca40940a0d2f0c295bdbd0b8a8640c47..5d96261af35756a4d3850145474ca045a5bc9c1c 100644 (file)
@@ -39,7 +39,7 @@
 
 
 #ifndef        lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.85 2006/11/25 17:28:54 christos Exp $")
+FILE_RCSID("@(#)$Id: softmagic.c,v 1.86 2006/12/08 20:31:07 christos Exp $")
 #endif /* lint */
 
 private int match(struct magic_set *, struct magic *, uint32_t,
@@ -68,9 +68,10 @@ protected int
 file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
 {
        struct mlist *ml;
+       int rv;
        for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
-               if (match(ms, ml->magic, ml->nmagic, buf, nbytes))
-                       return 1;
+               if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes)) != 0)
+                       return rv;
 
        return 0;
 }
@@ -113,6 +114,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
        int32_t oldoff = 0;
        int returnval = 0; /* if a match is found it is set to 1*/
        int firstline = 1; /* a flag to print X\n  X\n- X */
+       int printed_something = 0;
 
        if (check_mem(ms, cont_level) == -1)
                return -1;
@@ -123,7 +125,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                int flush = !mget(ms, &p, s, &magic[magindex], nbytes,
                    cont_level);
                if (flush) {
-                       if (magic[magindex].reln == '!') flush = 0;
+                       if (magic[magindex].reln == '!')
+                               flush = 0;
                } else {        
                        switch (magiccheck(ms, &p, &magic[magindex])) {
                        case -1:
@@ -152,6 +155,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                 */
                if (magic[magindex].desc[0]) {
                        need_separator = 1;
+                       printed_something = 1;
                        if (print_sep(ms, firstline) == -1)
                                return -1;
                }
@@ -197,6 +201,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                                 * make sure that we have a separator first.
                                 */
                                if (magic[magindex].desc[0]) {
+                                       printed_something = 1;
                                        if (print_sep(ms, firstline) == -1)
                                                return -1;
                                }
@@ -231,8 +236,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                        }
                }
                firstline = 0;
-               returnval = 1;
-               if ((ms->flags & MAGIC_CONTINUE) == 0) {
+               if (printed_something)
+                       returnval = 1;
+               if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
                        return 1; /* don't keep searching */
                }                       
        }
@@ -314,7 +320,8 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
                case -1:
                        return -1;
                case 1:
-                       if (snprintf(buf, sizeof(buf), "%hu", (unsigned short)v) < 0)
+                       if (snprintf(buf, sizeof(buf), "%hu",
+                           (unsigned short)v) < 0)
                                return -1;
                        if (file_printf(ms, m->desc, buf) == -1)
                                return -1;
@@ -1383,14 +1390,18 @@ magiccheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
                                ms->offset += range - 1;
                                break;
                        }
-                       if (range + slen >= p->search.buflen)
+                       if (range + slen >= p->search.buflen) {
+                               v = 1;
                                break;
+                       }
                        len = slen;
                        a = (unsigned char*)m->value.s;
                        b = (unsigned char*)p->search.buf + range;
                }
                free(p->search.buf);
                p->search.buf = NULL;
+               if (v)
+                       return 0;
                break;
        }
        default: