From: Christos Zoulas Date: Wed, 12 May 2004 14:53:01 +0000 (+0000) Subject: Add a check_format function to make sure that printf formats in magic X-Git-Tag: FILE5_05~866 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11c4b2263b75f96c2c35fc87104c3de03a7302c1;p=file Add a check_format function to make sure that printf formats in magic files make sense. --- diff --git a/src/apprentice.c b/src/apprentice.c index f8f4bd9b..5bcbf5cf 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -50,7 +50,7 @@ #endif #ifndef lint -FILE_RCSID("@(#)$Id: apprentice.c,v 1.75 2004/03/22 18:48:56 christos Exp $") +FILE_RCSID("@(#)$Id: apprentice.c,v 1.76 2004/05/12 14:53:01 christos Exp $") #endif /* lint */ #define EATAB {while (isascii((unsigned char) *l) && \ @@ -96,6 +96,7 @@ private int apprentice_map(struct magic_set *, struct magic **, uint32_t *, const char *); private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *, const char *); +private int check_format(struct magic *); private size_t maxmagic = 0; private size_t magicsize = sizeof(struct magic); @@ -704,6 +705,10 @@ GetDesc: while ((m->desc[i++] = *l++) != '\0' && i < MAXDESC) /* NULLBODY */; + if (ms->flags & MAGIC_CHECK) { + if (!check_format(m)) + return -1; + } #ifndef COMPILE_ONLY if (action == FILE_CHECK) { file_mdump(m); @@ -713,6 +718,57 @@ GetDesc: return 0; } +/* + * Check that the optional printf format in description matches + * the type of the magic. + */ +private int +check_format(struct magic *m) +{ + static const char *formats[] = { FILE_FORMAT_STRING }; + static const char *names[] = { FILE_FORMAT_NAME }; + char *ptr; + + for (ptr = m->desc; *ptr; ptr++) + if (*ptr == '%') + break; + if (*ptr == '\0') { + /* No format string; ok */ + return 1; + } + if (m->type >= sizeof(formats)/sizeof(formats[0])) { + file_magwarn("Internal error inconsistency between m->type" + " and format strings"); + return 0; + } + if (formats[m->type] == NULL) { + file_magwarn("No format string for `%s' with description `%s'", + m->desc, names[m->type]); + return 0; + } + for (; *ptr; ptr++) { + if (*ptr == 'l' || *ptr == 'h') { + /* XXX: we should really fix this one day */ + continue; + } + if (islower((unsigned char)*ptr) || *ptr == 'X') + break; + } + if (*ptr == '\0') { + /* Missing format string; bad */ + file_magwarn("Invalid format `%s' for type `%s'", + m->desc, names[m->type]); + return 0; + } + if (strchr(formats[m->type], *ptr) == NULL) { + file_magwarn("Printf format `%c' is not valid for type `%s'" + " in description `%s'", + *ptr, names[m->type], m->desc); + return 0; + } + return 1; +} + /* * Read a numeric value from a pointer, into the value union of a magic * pointer, according to the magic type. Update the string pointer to point diff --git a/src/file.h b/src/file.h index abdbdd9f..d5fe2cc9 100644 --- a/src/file.h +++ b/src/file.h @@ -32,7 +32,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$Id: file.h,v 1.60 2004/03/22 19:12:15 christos Exp $ + * @(#)$Id: file.h,v 1.61 2004/05/12 14:53:01 christos Exp $ */ #ifndef __file_h__ @@ -113,6 +113,50 @@ struct magic { #define FILE_BELDATE 15 #define FILE_LELDATE 16 #define FILE_REGEX 17 + +#define FILE_FORMAT_NAME \ +/* 0 */ "invalid 0", \ +/* 1 */ "byte", \ +/* 2 */ "short", \ +/* 3 */ "invalid 3", \ +/* 4 */ "long", \ +/* 5 */ "string", \ +/* 6 */ "date", \ +/* 7 */ "beshort", \ +/* 8 */ "belong", \ +/* 9 */ "bedate" \ +/* 10 */ "leshort", \ +/* 11 */ "lelong", \ +/* 12 */ "ledate", \ +/* 13 */ "pstring", \ +/* 14 */ "ldate", \ +/* 15 */ "beldate", \ +/* 16 */ "leldate", \ +/* 17 */ "regex", + +#define FILE_FMT_NUM "cduxXi" +#define FILE_FMT_STR "s" + +#define FILE_FORMAT_STRING \ +/* 0 */ NULL, \ +/* 1 */ FILE_FMT_NUM, \ +/* 2 */ FILE_FMT_NUM, \ +/* 3 */ NULL, \ +/* 4 */ FILE_FMT_NUM, \ +/* 5 */ FILE_FMT_STR, \ +/* 6 */ FILE_FMT_STR, \ +/* 7 */ FILE_FMT_NUM, \ +/* 8 */ FILE_FMT_NUM, \ +/* 9 */ FILE_FMT_STR, \ +/* 10 */ FILE_FMT_NUM, \ +/* 11 */ FILE_FMT_NUM, \ +/* 12 */ FILE_FMT_STR, \ +/* 13 */ FILE_FMT_STR, \ +/* 14 */ FILE_FMT_STR, \ +/* 15 */ FILE_FMT_STR, \ +/* 16 */ FILE_FMT_STR, \ +/* 17 */ FILE_FMT_STR, + /* Word 3 */ uint8_t in_op; /* operator for indirection */ uint8_t mask_op; /* operator for mask */