]> granicus.if.org Git - file/commitdiff
more support for negative buffers.
authorChristos Zoulas <christos@zoulas.com>
Fri, 3 Nov 2017 00:18:55 +0000 (00:18 +0000)
committerChristos Zoulas <christos@zoulas.com>
Fri, 3 Nov 2017 00:18:55 +0000 (00:18 +0000)
src/apprentice.c
src/buffer.c
src/file.h
src/softmagic.c

index d5bc3fbeb6d9275e1b46cc0eb5e4b94e23f10468..7af85c8ce42cf84db3528c054ae652d6f5b4ccc2 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.265 2017/11/02 20:25:39 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.266 2017/11/03 00:18:55 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -1916,6 +1916,13 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
                        file_magwarn(ms, "offset `%s' invalid", l);
                return -1;
        }
+        if (m->offset < 0 && cont_level != 0) {
+               if (ms->flags & MAGIC_CHECK) {
+                       file_magwarn(ms, "negative offset `%s' at level %u",
+                           l, cont_level);
+               }
+               return -1;
+       }
         l = t;
 
        if (m->flag & INDIR) {
index 293558e61b4293e302efc8b8162990e65584c8b2..a72b8ce63aa2f248e11682c64e916cf0b3660cd7 100644 (file)
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: buffer.c,v 1.1 2017/11/02 20:25:39 christos Exp $")
+FILE_RCSID("@(#)$File: buffer.c,v 1.2 2017/11/03 00:18:55 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
-#include <assert.h>
-#include <stdarg.h>
+#include <unistd.h>
 #include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#if defined(HAVE_WCHAR_H)
-#include <wchar.h>
-#endif
-#if defined(HAVE_WCTYPE_H)
-#include <wctype.h>
-#endif
-#if defined(HAVE_LIMITS_H)
-#include <limits.h>
-#endif
-
+#include <sys/stat.h>
 
 void
 buffer_init(struct buffer *b, int fd, const void *data, size_t len)
@@ -62,3 +50,31 @@ buffer_fini(struct buffer *b)
 {
        free(b->ebuf);
 }
+
+int
+buffer_fill(const struct buffer *bb)
+{
+       // XXX: should be cached?
+       struct stat st;
+       struct buffer *b = CCAST(struct buffer *, bb);
+
+       if (b->elen != 0)
+               return b->elen == (size_t)~0 ? -1 : 0;
+
+       if (b->fd == -1 || fstat(b->fd, &st) == -1 || !S_ISREG(st.st_mode))
+               goto out;
+
+       b->elen =  (size_t)st.st_size < b->flen ? (size_t)st.st_size : b->flen;
+       if ((b->ebuf = malloc(b->elen)) == NULL)
+               goto out;
+
+       if (pread(b->fd, b->ebuf, b->elen, st.st_size - b->elen) == -1) {
+               free(b->ebuf);
+               goto out;
+       }
+
+       return 0;
+out:
+       b->elen = (size_t)~0;
+       return -1;
+}
index 214b675ac7f71659d503c12340434d5bdfa317f0..59fd87f5f30fb67d060853a6d4047b207225b37f 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.186 2017/11/02 20:25:39 christos Exp $
+ * @(#)$File: file.h,v 1.187 2017/11/03 00:18:55 christos Exp $
  */
 
 #ifndef __file_h__
@@ -504,6 +504,7 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *,
 
 protected void buffer_init(struct buffer *, int, const void *, size_t);
 protected void buffer_fini(struct buffer *);
+protected int buffer_fill(const struct buffer *);
 
 #if defined(HAVE_LOCALE_H)
 #include <locale.h>
index 685b12704396236b01474dcfee6046e9e1f0a66d..7d43316577de9396f0491bd7d6dd3302d9cc010d 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.251 2017/11/02 20:25:39 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.252 2017/11/03 00:18:55 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -1345,10 +1345,10 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
     int flip, uint16_t *indir_count, uint16_t *name_count,
     int *printed_something, int *need_separator, int *returnval)
 {
+       const unsigned char *s;
+       size_t nbytes;
+       uint32_t offset;
        struct buffer bb;
-       const unsigned char *s = b->fbuf;
-       size_t nbytes = b->flen;
-       uint32_t offset = ms->offset;
        intmax_t lhs;
        file_pushbuf_t *pb;
        int rv, oneed_separator, in_type;
@@ -1368,6 +1368,31 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                return -1;
        }
 
+       if (ms->offset < 0) {
+               if (cont_level > 0) {
+                       file_error(ms, 0, "negative offset %d at continuation"
+                           "level %u", ms->offset, cont_level);
+                       return -1;
+               }
+               if (buffer_fill(b) == -1)
+                       return -1;
+               if (o != 0) {
+                       // Not yet!
+                       file_magerror(ms, "non zero offset %zu at"
+                           " level %u", o, cont_level);
+                       return -1;
+               }
+               if ((size_t)-ms->offset > b->elen)
+                       return -1;
+               s = b->ebuf;
+               nbytes = b->elen;
+               offset = b->elen + ms->offset;
+       } else {
+               s = b->fbuf;
+               nbytes = b->flen;
+               offset = ms->offset;
+       }
+
        if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
            (uint32_t)nbytes, m) == -1)
                return -1;
@@ -1593,6 +1618,11 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                return rv;
 
        case FILE_USE:
+               if (ms->offset < 0) {
+                       file_magerror(ms, "negative offset not supported yet"
+                           " for USE magic");
+                       return -1;
+               }
                if (nbytes < offset)
                        return 0;
                rbuf = m->value.s;