From b54241cf8231cedee9f9dd9a9a9e9052993af6b5 Mon Sep 17 00:00:00 2001 From: Christos Zoulas Date: Fri, 3 Nov 2017 00:18:55 +0000 Subject: [PATCH] more support for negative buffers. --- src/apprentice.c | 9 ++++++++- src/buffer.c | 46 +++++++++++++++++++++++++++++++--------------- src/file.h | 3 ++- src/softmagic.c | 38 ++++++++++++++++++++++++++++++++++---- 4 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/apprentice.c b/src/apprentice.c index d5bc3fbe..7af85c8c 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -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) { diff --git a/src/buffer.c b/src/buffer.c index 293558e6..a72b8ce6 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -27,25 +27,13 @@ #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 -#include +#include #include -#include -#include -#if defined(HAVE_WCHAR_H) -#include -#endif -#if defined(HAVE_WCTYPE_H) -#include -#endif -#if defined(HAVE_LIMITS_H) -#include -#endif - +#include 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; +} diff --git a/src/file.h b/src/file.h index 214b675a..59fd87f5 100644 --- a/src/file.h +++ b/src/file.h @@ -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 diff --git a/src/softmagic.c b/src/softmagic.c index 685b1270..7d433165 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -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; -- 2.40.0