From: Christos Zoulas Date: Thu, 6 Nov 2008 23:22:53 +0000 (+0000) Subject: Handle ID3 files. X-Git-Tag: FILE5_00~38 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f511621ed212f77d3dfd9c594d2cc0d79acf3e3e;p=file Handle ID3 files. --- diff --git a/ChangeLog b/ChangeLog index 97e1d1f2..a756bdd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-11-06 18:18 Christos Zoulas + + * Handle ID3 format files. + 2008-11-06 23:00 Reuben Thomas * Fix --mime, --mime-type and --mime-encoding under new scheme. diff --git a/doc/magic.man b/doc/magic.man index db92b3e4..34fb5cfc 100644 --- a/doc/magic.man +++ b/doc/magic.man @@ -1,4 +1,4 @@ -.\" $File: magic.man,v 1.57 2008/08/30 09:50:20 christos Exp $ +.\" $File: magic.man,v 1.58 2008/10/18 20:47:47 christos Exp $ .Dd August 30, 2008 .Dt MAGIC __FSECTION__ .Os @@ -84,6 +84,8 @@ local time rather than UTC. .It Dv qldate An eight-byte value interpreted as a UNIX-style date, but interpreted as local time rather than UTC. +.It Dv beid3 +A 32-bit ID3 length in big-endian byte order. .It Dv beshort A two-byte value in big-endian byte order. .It Dv belong @@ -110,6 +112,8 @@ interpreted as a UNIX-style date, but interpreted as local time rather than UTC. .It Dv bestring16 A two-byte unicode (UCS16) string in big-endian byte order. +.It Dv leid3 +A 32-bit ID3 length in little-endian byte order. .It Dv leshort A two-byte value in little-endian byte order. .It Dv lelong @@ -145,6 +149,8 @@ interpreted as a UNIX date. A four-byte value in middle-endian (PDP-11) byte order, interpreted as a UNIX-style date, but interpreted as local time rather than UTC. +.It Dv indirect +Starting at the given offset, consult the magic database again. .It Dv regex A regular expression match in extended POSIX regular expression syntax (like egrep). Regular expressions can take exponential time to @@ -366,12 +372,12 @@ the file. The value at that offset is read, and is used again as an offset in the file. Indirect offsets are of the form: -.Em (( x [.[bslBSL]][+\-][ y ]) . +.Em (( x [.[bislBISL]][+\-][ y ]) . The value of .Em x is used as an offset in the file. -A byte, short or long is read at that offset depending on the -.Em [bslBSLm] +A byte, id3 length, short or long is read at that offset depending on the +.Em [bislBISLm] type specifier. The capitalized types interpret the number as a big endian value, whereas the small letter versions interpret the number as a little diff --git a/magic/Magdir/audio b/magic/Magdir/audio index 872b29b2..f4a43cde 100644 --- a/magic/Magdir/audio +++ b/magic/Magdir/audio @@ -286,7 +286,16 @@ # SGI SoundTrack 0 string _SGI_SoundTrack SGI SoundTrack project file # ID3 version 2 tags -0 string ID3 Audio file with ID3 version 2. +0 string ID3 Audio file with ID3 version 2 +>3 byte x \b.%d +>4 byte x \b.%d +>>5 byte &0x80 \b, unsynchronized frames +>>5 byte &0x40 \b, extended header +>>5 byte &0x20 \b, experimental +>>5 byte &0x10 \b, footer present +>(6.I) indirect x \b, contains: + +0 string this\ is\ crap # Such a file is often an MP3 file, but this will give false positives #!:mime audio/mpeg >3 ubyte <0xff \b%d diff --git a/src/apprentice.c b/src/apprentice.c index 7edcb56c..acd3fedf 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.143 2008/10/30 10:54:07 rrt Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.144 2008/11/04 16:38:28 christos Exp $") #endif /* lint */ #include "magic.h" @@ -217,6 +217,9 @@ static const struct type_tbl_s { { XX("double"), FILE_DOUBLE, FILE_FMT_DOUBLE }, { XX("bedouble"), FILE_BEDOUBLE, FILE_FMT_DOUBLE }, { XX("ledouble"), FILE_LEDOUBLE, FILE_FMT_DOUBLE }, + { XX("leid3"), FILE_LEID3, FILE_FMT_NUM }, + { XX("beid3"), FILE_BEID3, FILE_FMT_NUM }, + { XX("indirect"), FILE_INDIRECT, FILE_FMT_NONE }, { XX_NULL, FILE_INVALID, FILE_FMT_NONE }, # undef XX # undef XX_NULL @@ -873,6 +876,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) case FILE_REGEX: case FILE_SEARCH: case FILE_DEFAULT: + case FILE_INDIRECT: break; default: if (ms->flags & MAGIC_CHECK) @@ -1189,6 +1193,12 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp, case 'G': m->in_type = FILE_BEDOUBLE; break; + case 'i': + m->in_type = FILE_LEID3; + break; + case 'I': + m->in_type = FILE_BEID3; + break; default: if (ms->flags & MAGIC_CHECK) file_magwarn(ms, diff --git a/src/file.h b/src/file.h index 53e69237..911c453c 100644 --- a/src/file.h +++ b/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.113 2008/11/04 16:48:42 christos Exp $ + * @(#)$File: file.h,v 1.114 2008/11/06 21:17:45 rrt Exp $ */ #ifndef __file_h__ @@ -183,7 +183,10 @@ struct magic { #define FILE_DOUBLE 36 #define FILE_BEDOUBLE 37 #define FILE_LEDOUBLE 38 -#define FILE_NAMES_SIZE 39/* size of array to contain all names */ +#define FILE_BEID3 39 +#define FILE_LEID3 40 +#define FILE_INDIRECT 41 +#define FILE_NAMES_SIZE 42/* size of array to contain all names */ #define IS_STRING(t) \ ((t) == FILE_STRING || \ diff --git a/src/softmagic.c b/src/softmagic.c index 597c27b0..6eae1651 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.128 2008/11/06 21:17:45 rrt Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.129 2008/11/06 22:49:08 rrt Exp $") #endif /* lint */ #include "magic.h" @@ -535,6 +535,10 @@ mprint(struct magic_set *ms, struct magic *m) t = ms->offset; break; + case FILE_INDIRECT: + t = ms->offset; + break; + default: file_magerror(ms, "invalid m->type (%d) in mprint()", m->type); return -1; @@ -929,9 +933,11 @@ mget(struct magic_set *ms, const unsigned char *s, off = q->l; break; case FILE_BELONG: + case FILE_BEID3: off = (int32_t)((q->hl[0]<<24)|(q->hl[1]<<16)| (q->hl[2]<<8)|(q->hl[3])); break; + case FILE_LEID3: case FILE_LELONG: off = (int32_t)((q->hl[3]<<24)|(q->hl[2]<<16)| (q->hl[1]<<8)|(q->hl[0])); @@ -1119,6 +1125,7 @@ mget(struct magic_set *ms, const unsigned char *s, offset = ~offset; break; case FILE_BELONG: + case FILE_BEID3: if (nbytes < (offset + 4)) return 0; if (off) { @@ -1189,6 +1196,7 @@ mget(struct magic_set *ms, const unsigned char *s, offset = ~offset; break; case FILE_LELONG: + case FILE_LEID3: if (nbytes < (offset + 4)) return 0; if (off) { @@ -1365,8 +1373,21 @@ mget(struct magic_set *ms, const unsigned char *s, break; } - if (m->flag & INDIROFFADD) + switch (m->in_type) { + case FILE_LEID3: + case FILE_BEID3: + offset = ((((offset >> 0) & 0x7f) << 0) | + (((offset >> 8) & 0x7f) << 7) | + (((offset >> 16) & 0x7f) << 14) | + (((offset >> 24) & 0x7f) << 21)) + 10; + break; + default: + break; + } + + if (m->flag & INDIROFFADD) { offset += ms->c.li[cont_level-1].off; + } if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1) return -1; ms->offset = offset; @@ -1432,6 +1453,12 @@ mget(struct magic_set *ms, const unsigned char *s, return 0; break; + case FILE_INDIRECT: + if (file_printf(ms, m->desc) == -1) + return -1; + return file_softmagic(ms, s + offset, nbytes - offset, + BINTEST); + case FILE_DEFAULT: /* nothing to check */ default: break; @@ -1730,6 +1757,8 @@ magiccheck(struct magic_set *ms, struct magic *m) return -1; break; } + case FILE_INDIRECT: + return 1; default: file_magerror(ms, "invalid type %d in magiccheck()", m->type); return -1;