summaryrefslogtreecommitdiff
path: root/file/src/softmagic.c
diff options
context:
space:
mode:
Diffstat (limited to 'file/src/softmagic.c')
-rw-r--r--file/src/softmagic.c123
1 files changed, 81 insertions, 42 deletions
diff --git a/file/src/softmagic.c b/file/src/softmagic.c
index dfb93019e..82bc72930 100644
--- a/file/src/softmagic.c
+++ b/file/src/softmagic.c
@@ -12,11 +12,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Ian F. Darwin and others.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -44,27 +39,29 @@
#ifndef lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.66 2004/07/24 20:38:56 christos Exp $")
+FILE_RCSID("@(#)$Id: softmagic.c,v 1.72 2004/11/24 17:38:25 christos Exp $")
#endif /* lint */
private int match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
const unsigned char *s, size_t nbytes)
/*@globals fileSystem @*/
/*@modifies ms, magic, fileSystem @*/;
-private int mget(struct magic_set *ms, union VALUETYPE *p,
- const unsigned char *s, struct magic *m, size_t nbytes)
+private int mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
+ struct magic *m, size_t nbytes)
/*@globals fileSystem @*/
/*@modifies ms, p, m, fileSystem @*/;
private int mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
/*@globals fileSystem @*/
/*@modifies ms, p, fileSystem @*/;
-private int32_t mprint(struct magic_set *ms, union VALUETYPE *p,
- struct magic *m)
+private int32_t mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
/*@globals fileSystem @*/
/*@modifies ms, p, fileSystem @*/;
private void mdebug(uint32_t offset, const char *str, size_t len)
/*@globals fileSystem @*/
/*@modifies fileSystem @*/;
+private int mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
+ const unsigned char *s, size_t offset, size_t nbytes)
+ /*@modifies ms, p @*/;
private int mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
/*@modifies ms, p @*/;
private int check_mem(struct magic_set *ms, unsigned int level)
@@ -289,6 +286,8 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
case FILE_STRING:
case FILE_PSTRING:
+ case FILE_BESTRING16:
+ case FILE_LESTRING16:
if (m->reln == '=') {
if (file_printf(ms, m->desc, m->value.s) == -1)
return -1;
@@ -439,28 +438,30 @@ mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
p->l = ~p->l;
return 1;
case FILE_STRING:
+ case FILE_BESTRING16:
+ case FILE_LESTRING16:
{
- int n;
+ size_t len;
/* Null terminate and eat *trailing* return */
p->s[sizeof(p->s) - 1] = '\0';
- n = strlen(p->s) - 1;
- if (p->s[n] == '\n')
- p->s[n] = '\0';
+ len = strlen(p->s);
+ if (len-- && p->s[len] == '\n')
+ p->s[len] = '\0';
return 1;
}
case FILE_PSTRING:
{
char *ptr1 = p->s, *ptr2 = ptr1 + 1;
- unsigned int n = *p->s;
- if (n >= sizeof(p->s))
- n = sizeof(p->s) - 1;
- while (n--)
+ size_t len = *p->s;
+ if (len >= sizeof(p->s))
+ len = sizeof(p->s) - 1;
+ while (len--)
*ptr1++ = *ptr2++;
*ptr1 = '\0';
- n = strlen(p->s) - 1;
- if (p->s[n] == '\n')
- p->s[n] = '\0';
+ len = strlen(p->s);
+ if (len-- && p->s[len] == '\n')
+ p->s[len] = '\0';
return 1;
}
case FILE_BESHORT:
@@ -616,12 +617,10 @@ mdebug(uint32_t offset, const char *str, size_t len)
}
private int
-mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
- struct magic *m, size_t nbytes)
+mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
+ const unsigned char *s, size_t offset, size_t nbytes)
{
- uint32_t offset = m->offset;
-
- if (m->type == FILE_REGEX) {
+ if (type == FILE_REGEX && indir == 0) {
/*
* offset is interpreted as last line to search,
* (starting at 1), not as bytes-from start-of-file
@@ -637,18 +636,59 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
last = b;
if (last != NULL)
*last = '\0';
- } else if (offset + sizeof(union VALUETYPE) <= nbytes)
- memcpy(p, s + offset, sizeof(union VALUETYPE));
- else {
- /*
- * the usefulness of padding with zeroes eludes me, it
- * might even cause problems
- */
- memset(p, 0, sizeof(union VALUETYPE));
- if (offset < nbytes)
- memcpy(p, s + offset, nbytes - offset);
+ return 0;
}
+ if (indir == 0 && (type == FILE_BESTRING16 || type == FILE_LESTRING16))
+ {
+ const char *src = s + offset;
+ const char *esrc = s + nbytes;
+ char *dst = p->s, *edst = &p->s[sizeof(p->s) - 1];
+
+ if (type == FILE_BESTRING16)
+ src++;
+
+ for (;src < esrc; src++, dst++) {
+ if (dst < edst)
+ *dst = *src++;
+ else
+ break;
+ if (*dst == '\0')
+ *dst = ' ';
+ }
+ *edst = '\0';
+ return 0;
+ }
+
+ if (offset >= nbytes) {
+ (void)memset(p, '\0', sizeof(*p));
+ return 0;
+ }
+ if (nbytes - offset < sizeof(*p))
+ nbytes = nbytes - offset;
+ else
+ nbytes = sizeof(*p);
+
+ (void)memcpy(p, s + offset, nbytes);
+
+ /*
+ * the usefulness of padding with zeroes eludes me, it
+ * might even cause problems
+ */
+ if (nbytes < sizeof(*p))
+ (void)memset(((char *)p) + nbytes, '\0', sizeof(*p) - nbytes);
+ return 0;
+}
+
+private int
+mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
+ struct magic *m, size_t nbytes)
+{
+ uint32_t offset = m->offset;
+
+ if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes) == -1)
+ return -1;
+
/* Verify we have enough data to match magic type */
switch (m->type) {
case FILE_BYTE:
@@ -1035,11 +1075,8 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
break;
}
- if (nbytes < sizeof(union VALUETYPE) ||
- nbytes - sizeof(union VALUETYPE) < offset)
- return 0;
-
- memcpy(p, s + offset, sizeof(union VALUETYPE));
+ if (mcopy(ms, p, m->type, 0, s, offset, nbytes) == -1)
+ return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
mdebug(offset, (char *)(void *)p,
@@ -1088,6 +1125,8 @@ mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
break;
case FILE_STRING:
+ case FILE_BESTRING16:
+ case FILE_LESTRING16:
case FILE_PSTRING:
{
/*
@@ -1147,8 +1186,8 @@ mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
file_error(ms, 0, "regex error %d, (%s)", rc, errmsg);
return -1;
} else {
- rc = regexec(&rx, p->buf, 0, 0, 0);
/*@-immediatetrans -moduncon -noeffectuncon @*/ /* regfree annotate bogus only @*/
+ rc = regexec(&rx, p->buf, 0, 0, 0);
regfree(&rx);
/*@=immediatetrans =moduncon =noeffectuncon @*/
free(p->buf);