From: Christos Zoulas Date: Tue, 3 May 1994 17:58:23 +0000 (+0000) Subject: changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned X-Git-Tag: FILE3_27~117 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7308bbc7ca1dec3f60d435c7a33bd483bb2cae47;p=file changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned --- diff --git a/doc/magic.man b/doc/magic.man index d504a5d7..7c2788e9 100644 --- a/doc/magic.man +++ b/doc/magic.man @@ -51,11 +51,14 @@ A four-byte value (on most systems) in little-endian byte order. A four-byte value (on most systems) in little-endian byte order, interpreted as a unix date. .RE +.PP The numeric types may optionally be followed by .B & and a numeric value, to specify that the value is to be AND'ed with the -numeric value before any comparisons are done. +numeric value before any comparisons are done. Prepending a +.B u +to the type indicates that ordered comparisons should be unsigned. .IP test The value to be compared with the value from the file. If the type is numeric, this value @@ -188,4 +191,4 @@ indirect offsets. .\" the changes I posted to the S5R2 version. .\" .\" Modified for Ian Darwin's version of the file command. -.\" @(#)$Id: magic.man,v 1.10 1993/02/19 14:22:46 ian Exp $ +.\" @(#)$Id: magic.man,v 1.11 1994/05/03 17:58:23 christos Exp $ diff --git a/src/apprentice.c b/src/apprentice.c index 6fad93c1..e1b4f455 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -33,17 +33,17 @@ #ifndef lint static char *moduleid = - "@(#)$Id: apprentice.c,v 1.18 1993/09/23 20:19:42 christos Exp $"; + "@(#)$Id: apprentice.c,v 1.19 1994/05/03 17:58:23 christos Exp $"; #endif /* lint */ #define EATAB {while (isascii((unsigned char) *l) && \ isspace((unsigned char) *l)) ++l;} -static int getvalue __P((struct magic *, char **)); -static int hextoint __P((int)); -static char *getstr __P((char *, char *, int, int *)); -static int parse __P((char *, int *, int)); +static int getvalue __P((struct magic *, char **)); +static int hextoint __P((int)); +static char *getstr __P((char *, char *, int, int *)); +static int parse __P((char *, int *, int)); static int maxmagic = 0; @@ -75,7 +75,7 @@ int check; /* non-zero? checking-only run. */ else exit(1); } - + /* parse it */ if (check) /* print silly verbose header for USG compat. */ (void) printf("cont\toffset\ttype\topcode\tmask\tvalue\tdesc\n"); @@ -94,6 +94,47 @@ int check; /* non-zero? checking-only run. */ return errs ? -1 : 0; } +/* + * extend the sign bit if the comparison is to be signed + */ +unsigned long +signextend(m, v) +struct magic *m; +unsigned long v; +{ + if (!(m->flag & UNSIGNED)) + switch(m->type) { + /* + * Do not remove the casts below. They are + * vital. When later compared with the data, + * the sign extension must have happened. + */ + case BYTE: + v = (char) v; + break; + case SHORT: + case BESHORT: + case LESHORT: + v = (short) v; + break; + case DATE: + case BEDATE: + case LEDATE: + case LONG: + case BELONG: + case LELONG: + v = (long) v; + break; + case STRING: + break; + default: + magwarn("can't happen: m->type=%d\n", + m->type); + return -1; + } + return v; +} + /* * parse one line from magic file, put into magic[index++] if valid */ @@ -191,6 +232,11 @@ int *ndx, check; #define NLELONG 6 #define NLEDATE 6 + if (*l == 'u') { + ++l; + m->flag |= UNSIGNED; + } + /* get type, skip it */ if (strncmp(l, "byte", NBYTE)==0) { m->type = BYTE; @@ -232,9 +278,9 @@ int *ndx, check; /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ if (*l == '&') { ++l; - m->mask = strtol(l, &l, 0); + m->mask = signextend(m, strtol(l, &l, 0)); } else - m->mask = 0L; + m->mask = ~0L; EATAB; switch (*l) { @@ -313,36 +359,9 @@ char **p; if (m->type == STRING) { *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen); m->vallen = slen; - } else { - if (m->reln != 'x') { - switch(m->type) { - /* - * Do not remove the casts below. They are vital. - * When later compared with the data, the sign - * extension must have happened. - */ - case BYTE: - m->value.l = (char) strtol(*p,p,0); - break; - case SHORT: - case BESHORT: - case LESHORT: - m->value.l = (short) strtol(*p,p,0); - break; - case DATE: - case BEDATE: - case LEDATE: - case LONG: - case BELONG: - case LELONG: - m->value.l = (long) strtol(*p,p,0); - break; - default: - magwarn("can't happen: m->type=%d\n", m->type); - return -1; - } - } - } + } else + if (m->reln != 'x') + m->value.l = signextend(m, strtol(*p, p, 0)); return 0; } diff --git a/src/file.h b/src/file.h index 39874a1b..12d5c6f9 100644 --- a/src/file.h +++ b/src/file.h @@ -1,6 +1,6 @@ /* * file.h - definitions for file(1) program - * @(#)$Id: file.h,v 1.18 1993/10/27 20:59:05 christos Exp $ + * @(#)$Id: file.h,v 1.19 1994/05/03 17:58:23 christos Exp $ * * Copyright (c) Ian F. Darwin, 1987. * Written by Ian F. Darwin. @@ -34,6 +34,7 @@ struct magic { short flag; #define INDIR 1 /* if '>(...)' appears, */ +#define UNSIGNED 2 /* comparison is unsigned */ short cont_level; /* level of ">" */ struct { char type; /* byte short long */ @@ -55,14 +56,14 @@ struct magic { #define LELONG 11 #define LEDATE 12 union VALUETYPE { - char b; - short h; - long l; + unsigned char b; + unsigned short h; + unsigned long l; char s[MAXstring]; unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */ unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */ } value; /* either number or string */ - long mask; /* mask before comparison with value */ + unsigned long mask; /* mask before comparison with value */ char nospflag; /* supress space character */ char desc[MAXDESC]; /* description */ }; @@ -94,6 +95,7 @@ extern int softmagic __P((unsigned char *, int)); extern void tryit __P((unsigned char *, int, int)); extern int zmagic __P((unsigned char *, int)); extern void ckfprintf __P((FILE *, const char *, ...)); +extern unsigned long signextend __P((struct magic *, unsigned long)); diff --git a/src/patchlevel.h b/src/patchlevel.h index 499609d5..490a7d53 100644 --- a/src/patchlevel.h +++ b/src/patchlevel.h @@ -1,12 +1,15 @@ #define FILE_VERSION_MAJOR 3 -#define patchlevel 13 +#define patchlevel 14 /* * Patchlevel file for Ian Darwin's MAGIC command. - * $Id: patchlevel.h,v 1.13 1994/01/21 01:27:01 christos Exp $ + * $Id: patchlevel.h,v 1.14 1994/05/03 17:58:23 christos Exp $ * * $Log: patchlevel.h,v $ - * Revision 1.13 1994/01/21 01:27:01 christos + * Revision 1.14 1994/05/03 17:58:23 christos + * changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned + * + * Revision 1.13 1994/01/21 01:27:01 christos * Fixed null termination bug from Don Seeley at BSDI in ascmagic.c * * Revision 1.12 1993/10/27 20:59:05 christos diff --git a/src/print.c b/src/print.c index 7114a7bd..a91f4297 100644 --- a/src/print.c +++ b/src/print.c @@ -40,7 +40,7 @@ #ifndef lint static char *moduleid = - "@(#)$Id: print.c,v 1.20 1993/09/23 20:26:25 christos Exp $"; + "@(#)$Id: print.c,v 1.21 1994/05/03 17:58:23 christos Exp $"; #endif /* lint */ #define SZOF(a) (sizeof(a) / sizeof(a[0])) @@ -49,33 +49,29 @@ void mdump(m) struct magic *m; { - static char *offs[] = { "absolute", "offset", - "indirect", "indirect-offset" }; static char *typ[] = { "invalid", "byte", "short", "invalid", "long", "string", "date", "beshort", "belong", "bedate", "leshort", "lelong", "ledate" }; - (void) fprintf(stderr, "[%s,%d,", - (m->flag >= 0 && m->flag < SZOF(offs) ? offs[m->flag]: "*bad*"), - m->offset); - + (void) fputc('[', stderr); + (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7), + m->offset); if (m->flag & INDIR) - (void) fprintf(stderr, "(%s,%d),", - (m->in.type >= 0 && - m->in.type < SZOF(typ) ? - typ[(unsigned char) m->in.type] : "*bad*"), - m->in.offset); + (void) fprintf(stderr, "(%s,%d),", + (m->in.type >= 0 && m->in.type < SZOF(typ)) ? + typ[(unsigned char) m->in.type] : + "*bad*", + m->in.offset); - (void) fputs((m->type >= 0 && m->type < SZOF(typ)) ? - typ[(unsigned char) m->type] : - "*bad*", - stderr); + (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "", + (m->type >= 0 && m->type < SZOF(typ)) ? + typ[(unsigned char) m->type] : + "*bad*"); + if (m->mask != ~0L) + (void) fprintf(stderr, " & %.8x", m->mask); - if (m->reln == 'x') - (void) fputs(",*any*", stderr); - else - (void) fprintf(stderr, ",%c", m->reln); + (void) fprintf(stderr, ",%c", m->reln); if (m->reln != 'x') { switch (m->type) { diff --git a/src/softmagic.c b/src/softmagic.c index 5bcf0bf8..a89b0a76 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -34,7 +34,7 @@ #ifndef lint static char *moduleid = - "@(#)$Id: softmagic.c,v 1.24 1993/10/27 20:59:05 christos Exp $"; + "@(#)$Id: softmagic.c,v 1.25 1994/05/03 17:58:23 christos Exp $"; #endif /* lint */ static int match __P((unsigned char *, int)); @@ -173,22 +173,26 @@ union VALUETYPE *p; struct magic *m; { char *pp, *rt; - unsigned long mask = m->mask ? m->mask : ~0; + unsigned long v; + switch (m->type) { case BYTE: - (void) printf(m->desc, (unsigned char) p->b & mask); - break; + v = p->b; + break; + case SHORT: case BESHORT: case LESHORT: - (void) printf(m->desc, (unsigned short) p->h & mask); - break; + v = p->h; + break; + case LONG: case BELONG: case LELONG: - (void) printf(m->desc, (unsigned long) p->l & mask); + v = p->l; break; + case STRING: if (m->reln == '=') { (void) printf(m->desc, m->value.s); @@ -198,7 +202,8 @@ struct magic *m; *rt = '\0'; (void) printf(m->desc, p->s); } - break; + return; + case DATE: case BEDATE: case LEDATE: @@ -206,11 +211,14 @@ struct magic *m; if ((rt = strchr(pp, '\n')) != NULL) *rt = '\0'; (void) printf(m->desc, pp); - break; + return; default: error("invalid m->type (%d) in mprint().\n", m->type); /*NOTREACHED*/ } + + v = signextend(m, v) & m->mask; + (void) printf(m->desc, (unsigned char) v); } /* @@ -321,8 +329,9 @@ mcheck(p, m) union VALUETYPE* p; struct magic *m; { - register long l = m->value.l; - register long v; + register unsigned long l = m->value.l; + register unsigned long v; + int matched; if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) { fprintf(stderr, "BOINK"); @@ -373,42 +382,58 @@ struct magic *m; return 0;/*NOTREACHED*/ } - if (m->mask != 0L) - v &= m->mask; + v = signextend(m, v) & m->mask; switch (m->reln) { case 'x': if (debug) (void) fprintf(stderr, "%d == *any* = 1\n", v); - return 1; + matched = 1; + break; + case '!': if (debug) (void) fprintf(stderr, "%d != %d = %d\n", v, l, v != l); - return v != l; + matched = v != l; + break; + case '=': if (debug) (void) fprintf(stderr, "%d == %d = %d\n", v, l, v == l); - return v == l; + matched = v == l; + break; + case '>': if (debug) (void) fprintf(stderr, "%d > %d = %d\n", v, l, v > l); - return v > l; + matched = v > l; + break; + case '<': if (debug) (void) fprintf(stderr, "%d < %d = %d\n", v, l, v < l); - return v < l; + matched = v < l; + break; + case '&': if (debug) (void) fprintf(stderr, "((%x & %x) == %x) = %d\n", v, l, l, (v & l) == l); - return (v & l) == l; + matched = (v & l) == l; + break; + case '^': if (debug) (void) fprintf(stderr, "((%x & %x) != %x) = %d\n", v, l, l, (v & l) != l); - return (v & l) != l; + matched = (v & l) != l; + break; + default: + matched = 0; error("mcheck: can't happen: invalid relation %d.\n", m->reln); - return 0;/*NOTREACHED*/ + break;/*NOTREACHED*/ } + + return matched; }