#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"
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) {
#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)
{
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;
+}
*/
/*
* 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__
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>
#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"
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;
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;
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;