]> granicus.if.org Git - file/commitdiff
support for various formats of pascal strings.
authorChristos Zoulas <christos@zoulas.com>
Wed, 22 Dec 2010 18:14:05 +0000 (18:14 +0000)
committerChristos Zoulas <christos@zoulas.com>
Wed, 22 Dec 2010 18:14:05 +0000 (18:14 +0000)
ChangeLog
doc/magic.man
src/apprentice.c
src/file.h
src/softmagic.c

index eefdc712a4eae0955b5b8457bc2c5667cc2dc1cd..29e8724afe3fa4b95df7b740f7ebe99bcb1e8cec 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,20 @@
+2010-12-22  13:12  Christos Zoulas <christos@zoulas.com>
+
+       * Add pstring/BHhLl to specify the type of the length of pascal
+         strings.
+
 2010-11-26  18:39  Reuben Thomas <rrt@sc3d.org>
+
        * Fix "-e soft": it was ignored when softmagic was called
          during asciimagic.
        * Improve comments and use "unsigned char" in tar.h/is_tar.c.
 
 2010-11-05  17:26  Reuben Thomas <rrt@sc3d.org>
+
        * Make bug reporting addresses more visible.
 
 2010-11-01  18:35  Reuben Thomas <rrt@sc3d.org>
+
        * Add tcl magic from Gustaf Neumann
 
 2010-10-24  10:42  Christos Zoulas <christos@zoulas.com>
index 8afff15db571611b2463e777b86acde7a285bc82..1caa8dce0e38b4179a5ce82c0d1d164505c3366f 100644 (file)
@@ -1,4 +1,4 @@
-.\" $File: magic.man,v 1.63 2010/10/21 22:08:34 christos Exp $
+.\" $File: magic.man,v 1.64 2010/12/22 18:14:05 christos Exp $
 .Dd August 30, 2008
 .Dt MAGIC __FSECTION__
 .Os
@@ -71,8 +71,22 @@ characters in the magic match both lower and upper case characters in the
 target, whereas upper case characters in the magic only match uppercase
 characters in the target.
 .It Dv pstring
-A Pascal-style string where the first byte is interpreted as the an
+A Pascal-style string where the first byte/short/int is interpreted as the an
 unsigned length.
+The length defaults to byte and can be specified as a modifier.
+The following modifiers are supported:
+.Bl -tag -compact -width B
+.It B
+A byte length (default).
+.It H
+A 2 byte big endian length.
+.It h
+A 2 byte big little length.
+.It L
+A 4 byte big endian length.
+.It l
+A 4 byte big little length.
+.El
 The string is not NUL terminated.
 .It Dv date
 A four-byte value interpreted as a UNIX date.
index fe7401718675c5ce4a7e297b7c9646cbada41174..b512f6b90da7e763b508171a59c5ab7a78a56830 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.161 2010/10/07 00:33:20 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.162 2010/12/22 18:14:06 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -981,6 +981,11 @@ string_modifier_check(struct magic_set *ms, struct magic *m)
        if ((ms->flags & MAGIC_CHECK) == 0)
                return 0;
 
+       if (m->type != FILE_PSTRING && (m->str_flags & PSTRING_LEN) != 0) {
+               file_magwarn(ms,
+                   "'/BHhLl' modifiers are only allowed for pascal strings\n");
+               return -1;
+       }
        switch (m->type) {
        case FILE_BESTRING16:
        case FILE_LESTRING16:
@@ -1357,7 +1362,7 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
                ++l;
        }
        m->str_range = 0;
-       m->str_flags = 0;
+       m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
        m->num_mask = 0;
        if ((op = get_op(*l)) != -1) {
                if (!IS_STRING(m->type)) {
@@ -1412,6 +1417,32 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
                                case CHAR_TEXTTEST:
                                        m->str_flags |= STRING_TEXTTEST;
                                        break;
+                               case CHAR_PSTRING_1_LE:
+                                       if (m->type != FILE_PSTRING)
+                                               goto bad;
+                                       m->str_flags |= PSTRING_1_LE;
+                                       break;
+                               case CHAR_PSTRING_2_BE:
+                                       if (m->type != FILE_PSTRING)
+                                               goto bad;
+                                       m->str_flags |= PSTRING_2_BE;
+                                       break;
+                               case CHAR_PSTRING_2_LE:
+                                       if (m->type != FILE_PSTRING)
+                                               goto bad;
+                                       m->str_flags |= PSTRING_2_LE;
+                                       break;
+                               case CHAR_PSTRING_4_BE:
+                                       if (m->type != FILE_PSTRING)
+                                               goto bad;
+                                       m->str_flags |= PSTRING_4_BE;
+                                       break;
+                               case CHAR_PSTRING_4_LE:
+                                       if (m->type != FILE_PSTRING)
+                                               goto bad;
+                                       m->str_flags |= PSTRING_4_LE;
+                                       break;
+                               bad:
                                default:
                                        if (ms->flags & MAGIC_CHECK)
                                                file_magwarn(ms,
@@ -2045,7 +2076,7 @@ out:
        *p = '\0';
        m->vallen = CAST(unsigned char, (p - origp));
        if (m->type == FILE_PSTRING)
-               m->vallen++;
+               m->vallen += file_pstring_length_size(m);
        return s;
 }
 
@@ -2434,3 +2465,40 @@ bs1(struct magic *m)
                m->num_mask = swap8(m->num_mask);
        }
 }
+
+protected size_t 
+file_pstring_length_size(const struct magic *m)
+{
+       switch (m->str_flags & PSTRING_LEN) {
+       case PSTRING_1_LE:
+               return 1;
+       case PSTRING_2_LE:
+       case PSTRING_2_BE:
+               return 2;
+       case PSTRING_4_LE:
+       case PSTRING_4_BE:
+               return 4;
+       default:
+               abort();        /* Impossible */
+               return 1;
+       }
+}
+protected size_t
+file_pstring_get_length(const struct magic *m, const char *s)
+{
+       switch (m->str_flags & PSTRING_LEN) {
+       case PSTRING_1_LE:
+               return *s;
+       case PSTRING_2_LE:
+               return (s[1] << 8) | s[0];
+       case PSTRING_2_BE:
+               return (s[0] << 8) | s[1];
+       case PSTRING_4_LE:
+               return (s[3] << 24) | (s[2] << 16) | (s[1] << 8) | s[0];
+       case PSTRING_4_BE:
+               return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+       default:
+               abort();        /* Impossible */
+               return 1;
+       }
+}
index 2e8bdca8447e433b5af559210a3b3108bfd5195a..5ff97c5aa74094dca8bd6781f8cea74ccecad4fc 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.128 2010/11/23 18:02:08 christos Exp $
+ * @(#)$File: file.h,v 1.129 2010/12/22 18:14:06 christos Exp $
  */
 
 #ifndef __file_h__
@@ -294,6 +294,14 @@ struct magic {
 #define REGEX_OFFSET_START                     BIT(4)
 #define STRING_TEXTTEST                                BIT(5)
 #define STRING_BINTEST                         BIT(6)
+#define PSTRING_1_BE                           BIT(7)
+#define PSTRING_1_LE                           BIT(7)
+#define PSTRING_2_BE                           BIT(8)
+#define PSTRING_2_LE                           BIT(9)
+#define PSTRING_4_BE                           BIT(10)
+#define PSTRING_4_LE                           BIT(11)
+#define PSTRING_LEN    \
+    (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE)
 #define CHAR_COMPACT_WHITESPACE                        'W'
 #define CHAR_COMPACT_OPTIONAL_WHITESPACE       'w'
 #define CHAR_IGNORE_LOWERCASE                  'c'
@@ -301,6 +309,12 @@ struct magic {
 #define CHAR_REGEX_OFFSET_START                        's'
 #define CHAR_TEXTTEST                          't'
 #define CHAR_BINTEST                           'b'
+#define CHAR_PSTRING_1_BE                      'B'
+#define CHAR_PSTRING_1_LE                      'B'
+#define CHAR_PSTRING_2_BE                      'H'
+#define CHAR_PSTRING_2_LE                      'h'
+#define CHAR_PSTRING_4_BE                      'L'
+#define CHAR_PSTRING_4_LE                      'l'
 #define STRING_IGNORE_CASE             (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
 #define STRING_DEFAULT_RANGE           100
 
@@ -411,6 +425,8 @@ protected ssize_t sread(int, void *, size_t, int);
 protected int file_check_mem(struct magic_set *, unsigned int);
 protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
     size_t *);
+protected size_t file_pstring_length_size(const struct magic *);
+protected size_t file_pstring_get_length(const struct magic *, const char *);
 #ifdef __EMX__
 protected int file_os2_apptype(struct magic_set *, const char *, const void *,
     size_t);
index dd22e82cd58f585202da0d03377268250b5dcbff..0524bdd80dc01353038069e255800221a2c89480 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.142 2010/10/24 14:42:07 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.143 2010/12/22 18:14:06 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -168,6 +168,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                        continue;
                }
 
+               if ((e = handle_annotation(ms, m)) != 0)
+                       return e;
                /*
                 * If we are going to print something, we'll need to print
                 * a blank before we print something else.
@@ -175,8 +177,6 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                if (*m->desc) {
                        need_separator = 1;
                        printed_something = 1;
-                       if ((e = handle_annotation(ms, m)) != 0)
-                               return e;
                        if (print_sep(ms, firstline) == -1)
                                return -1;
                }
@@ -251,13 +251,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                                        ms->c.li[cont_level].got_match = 0;
                                        break;
                                }
+                               if ((e = handle_annotation(ms, m)) != 0)
+                                       return e;
                                /*
                                 * If we are going to print something,
                                 * make sure that we have a separator first.
                                 */
                                if (*m->desc) {
-                                       if ((e = handle_annotation(ms, m)) != 0)
-                                               return e;
                                        if (!printed_something) {
                                                printed_something = 1;
                                                if (print_sep(ms, firstline)
@@ -449,7 +449,7 @@ mprint(struct magic_set *ms, struct magic *m)
                                return -1;
                        t = ms->offset + strlen(p->s);
                        if (m->type == FILE_PSTRING)
-                               t++;
+                               t += file_pstring_length_size(m);
                }
                break;
 
@@ -614,7 +614,7 @@ moffset(struct magic_set *ms, struct magic *m)
                                p->s[strcspn(p->s, "\n")] = '\0';
                        t = CAST(uint32_t, (ms->offset + strlen(p->s)));
                        if (m->type == FILE_PSTRING)
-                               t++;
+                               t += file_pstring_length_size(m);
                        return t;
                }
 
@@ -799,8 +799,8 @@ mconvert(struct magic_set *ms, struct magic *m)
                return 1;
        }
        case FILE_PSTRING: {
-               char *ptr1 = p->s, *ptr2 = ptr1 + 1;
-       size_t len = *p->s;
+               char *ptr1 = p->s, *ptr2 = ptr1 + file_pstring_length_size(m);
+               size_t len = file_pstring_get_length(m, ptr1);
                if (len >= sizeof(p->s))
                        len = sizeof(p->s) - 1;
                while (len--)