summaryrefslogtreecommitdiffstats
path: root/contrib/file/apprentice.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/file/apprentice.c')
-rw-r--r--contrib/file/apprentice.c117
1 files changed, 90 insertions, 27 deletions
diff --git a/contrib/file/apprentice.c b/contrib/file/apprentice.c
index 714c86c..ba7f783 100644
--- a/contrib/file/apprentice.c
+++ b/contrib/file/apprentice.c
@@ -30,6 +30,11 @@
*/
#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: apprentice.c,v 1.147 2009/02/03 20:27:51 christos Exp $")
+#endif /* lint */
+
#include "magic.h"
#include "patchlevel.h"
#include <stdlib.h>
@@ -40,18 +45,11 @@
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/param.h>
#ifdef QUICK
#include <sys/mman.h>
#endif
-#include <sys/types.h>
#include <dirent.h>
-#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.140 2008/07/20 04:02:15 christos Exp $")
-#endif /* lint */
-
#define EATAB {while (isascii((unsigned char) *l) && \
isspace((unsigned char) *l)) ++l;}
#define LOWCASE(l) (isupper((unsigned char) (l)) ? \
@@ -106,7 +104,7 @@ private void bs1(struct magic *);
private uint16_t swap2(uint16_t);
private uint32_t swap4(uint32_t);
private uint64_t swap8(uint64_t);
-private void mkdbname(const char *, char **, int);
+private char *mkdbname(struct magic_set *, const char *, int);
private int apprentice_map(struct magic_set *, struct magic **, uint32_t *,
const char *);
private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *,
@@ -115,8 +113,8 @@ private int check_format_type(const char *, int);
private int check_format(struct magic_set *, struct magic *);
private int get_op(char);
private int parse_mime(struct magic_set *, struct magic_entry *, const char *);
-private int parse_strength(struct magic_set *, struct magic_entry *,
- const char *);
+private int parse_strength(struct magic_set *, struct magic_entry *, const char *);
+private int parse_apple(struct magic_set *, struct magic_entry *, const char *);
private size_t maxmagic = 0;
@@ -131,6 +129,7 @@ private struct {
} bang[] = {
#define DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
DECLARE_FIELD(mime),
+ DECLARE_FIELD(apple),
DECLARE_FIELD(strength),
#undef DECLARE_FIELD
{ NULL, 0, NULL }
@@ -215,6 +214,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
@@ -590,7 +592,8 @@ set_test_type(struct magic *mstart, struct magic *m)
case FILE_SEARCH:
#ifndef COMPILE_ONLY
/* binary test if pattern is not text */
- if (file_looks_utf8(m->value.us, m->vallen, NULL, NULL) <= 0)
+ if (file_looks_utf8(m->value.us, (size_t)m->vallen, NULL,
+ NULL) <= 0)
mstart->flag |= BINTEST;
#endif
break;
@@ -706,6 +709,8 @@ apprentice_load(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
(void)fprintf(stderr, "%s\n", usg_hdr);
/* load directory or file */
+ /* FIXME: Read file names and sort them to prevent
+ non-determinism. See Debian bug #488562. */
if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
dir = opendir(fn);
if (dir) {
@@ -870,6 +875,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)
@@ -1186,6 +1192,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,
@@ -1475,6 +1487,38 @@ out:
}
/*
+ * Parse an Apple CREATOR/TYPE annotation from magic file and put it into magic[index - 1]
+ */
+private int
+parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+ size_t i;
+ const char *l = line;
+ struct magic *m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1];
+
+ if (m->apple[0] != '\0') {
+ file_magwarn(ms, "Current entry already has a APPLE type `%.8s',"
+ " new type `%s'", m->mimetype, l);
+ return -1;
+ }
+
+ EATAB;
+ for (i = 0; *l && ((isascii((unsigned char)*l) && isalnum((unsigned char)*l))
+ || strchr("-+/.", *l)) && i < sizeof(m->apple); m->apple[i++] = *l++)
+ continue;
+ if (i == sizeof(m->apple) && *l) {
+ if (ms->flags & MAGIC_CHECK)
+ file_magwarn(ms, "APPLE type `%s' truncated %zu",
+ line, i);
+ }
+
+ if (i > 0)
+ return 0;
+ else
+ return -1;
+}
+
+/*
* parse a MIME annotation line from magic file, put into magic[index - 1]
* if valid
*/
@@ -1492,10 +1536,8 @@ parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line)
}
EATAB;
- for (i = 0;
- *l && ((isascii((unsigned char)*l) && isalnum((unsigned char)*l))
- || strchr("-+/.", *l)) && i < sizeof(m->mimetype);
- m->mimetype[i++] = *l++)
+ for (i = 0; *l && ((isascii((unsigned char)*l) && isalnum((unsigned char)*l))
+ || strchr("-+/.", *l)) && i < sizeof(m->mimetype); m->mimetype[i++] = *l++)
continue;
if (i == sizeof(m->mimetype)) {
m->desc[sizeof(m->mimetype) - 1] = '\0';
@@ -2016,7 +2058,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
char *dbname = NULL;
void *mm = NULL;
- mkdbname(fn, &dbname, 0);
+ dbname = mkdbname(ms, fn, 0);
if (dbname == NULL)
goto error2;
@@ -2113,7 +2155,7 @@ apprentice_compile(struct magic_set *ms, struct magic **magicp,
char *dbname;
int rv = -1;
- mkdbname(fn, &dbname, 1);
+ dbname = mkdbname(ms, fn, 1);
if (dbname == NULL)
goto out;
@@ -2151,24 +2193,45 @@ private const char ext[] = ".mgc";
/*
* make a dbname
*/
-private void
-mkdbname(const char *fn, char **buf, int strip)
+private char *
+mkdbname(struct magic_set *ms, const char *fn, int strip)
{
- const char *p;
+ const char *p, *q;
+ char *buf;
+
if (strip) {
if ((p = strrchr(fn, '/')) != NULL)
fn = ++p;
}
- if ((p = strstr(fn, ext)) != NULL && p[sizeof(ext) - 1] == '\0')
- *buf = strdup(fn);
- else
- (void)asprintf(buf, "%s%s", fn, ext);
+ for (q = fn; *q; q++)
+ continue;
+ /* Look for .mgc */
+ for (p = ext + sizeof(ext) - 1; p >= ext && q >= fn; p--, q--)
+ if (*p != *q)
+ break;
- if (buf && *buf && strlen(*buf) > MAXPATHLEN) {
- free(*buf);
- *buf = NULL;
+ /* Did not find .mgc, restore q */
+ if (p >= ext)
+ while (*q)
+ q++;
+
+ q++;
+ /* Compatibility with old code that looked in .mime */
+ if (ms->flags & MAGIC_MIME) {
+ asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext);
+ if (access(buf, R_OK) != -1) {
+ ms->flags &= MAGIC_MIME_TYPE;
+ return buf;
+ }
+ free(buf);
}
+ asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext);
+
+ /* Compatibility with old code that looked in .mime */
+ if (strstr(p, ".mime") != NULL)
+ ms->flags &= MAGIC_MIME_TYPE;
+ return buf;
}
/*
OpenPOWER on IntegriCloud