+2008-11-06 18:18 Christos Zoulas <christos@zoulas.com>
+
+ * Handle ID3 format files.
+
2008-11-06 23:00 Reuben Thomas <rrt@sc3d.org>
* Fix --mime, --mime-type and --mime-encoding under new scheme.
-.\" $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
.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
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
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
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
# SGI SoundTrack <mpruett@sgi.com>
0 string _SGI_SoundTrack SGI SoundTrack project file
# ID3 version 2 tags <waschk@informatik.uni-rostock.de>
-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
#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"
{ 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
case FILE_REGEX:
case FILE_SEARCH:
case FILE_DEFAULT:
+ case FILE_INDIRECT:
break;
default:
if (ms->flags & MAGIC_CHECK)
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,
*/
/*
* 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__
#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 || \
#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"
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;
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]));
offset = ~offset;
break;
case FILE_BELONG:
+ case FILE_BEID3:
if (nbytes < (offset + 4))
return 0;
if (off) {
offset = ~offset;
break;
case FILE_LELONG:
+ case FILE_LEID3:
if (nbytes < (offset + 4))
return 0;
if (off) {
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;
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;
return -1;
break;
}
+ case FILE_INDIRECT:
+ return 1;
default:
file_magerror(ms, "invalid type %d in magiccheck()", m->type);
return -1;