+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>
-.\" $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
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.
#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"
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:
++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)) {
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,
*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;
}
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;
+ }
+}
*/
/*
* 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__
#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'
#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
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);
#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"
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.
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;
}
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)
return -1;
t = ms->offset + strlen(p->s);
if (m->type == FILE_PSTRING)
- t++;
+ t += file_pstring_length_size(m);
}
break;
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;
}
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--)