diff --git a/src/file.h b/src/file.h index 28f9bc7..f55d47f 100644 --- a/src/file.h +++ b/src/file.h @@ -446,6 +446,14 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *, #endif /* __EMX__ */ +typedef struct { + char *buf; + uint32_t offset; +} file_pushbuf_t; + +protected file_pushbuf_t *file_push_buffer(struct magic_set *); +protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *); + #ifndef COMPILE_ONLY extern const char *file_names[]; extern const size_t file_nnames; diff --git a/src/funcs.c b/src/funcs.c index 0d645eb..04bab02 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -459,3 +459,43 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep) return nm; } } + +protected file_pushbuf_t * +file_push_buffer(struct magic_set *ms) +{ + file_pushbuf_t *pb; + + if (ms->event_flags & EVENT_HAD_ERR) + return NULL; + + if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL) + return NULL; + + pb->buf = ms->o.buf; + pb->offset = ms->offset; + + ms->o.buf = NULL; + ms->offset = 0; + + return pb; +} + +protected char * +file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb) +{ + char *rbuf; + + if (ms->event_flags & EVENT_HAD_ERR) { + free(pb->buf); + free(pb); + return NULL; + } + + rbuf = ms->o.buf; + + ms->o.buf = pb->buf; + ms->offset = pb->offset; + + free(pb); + return rbuf; +} diff --git a/src/softmagic.c b/src/softmagic.c index ee979b9..3695add 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -60,6 +60,7 @@ private void cvt_32(union VALUETYPE *, const struct magic *); private void cvt_64(union VALUETYPE *, const struct magic *); #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) + /* * softmagic - lookup one file in parsed, in-memory copy of database * Passed the name and FILE * of one file to be typed. @@ -1060,6 +1061,9 @@ mget(struct magic_set *ms, const unsigned char *s, { uint32_t offset = ms->offset; union VALUETYPE *p = &ms->ms_value; + file_pushbuf_t *pb; + char *rbuf; + int rv; if (recursion_level >= 20) { file_error(ms, 0, "recursion nesting exceeded"); @@ -1620,16 +1624,34 @@ mget(struct magic_set *ms, const unsigned char *s, break; case FILE_INDIRECT: - if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 && - file_printf(ms, "%s", m->desc) == -1) - return -1; if (offset == 0) return 0; + if (nbytes < offset) - return 0; - return file_softmagic(ms, s + offset, nbytes - offset, + return 0; + + if ((pb = file_push_buffer(ms)) == NULL) + return -1; + + rv = file_softmagic(ms, s + offset, nbytes - offset, recursion_level, BINTEST, text); + if ((ms->flags & MAGIC_DEBUG) != 0) + fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); + + rbuf = file_pop_buffer(ms, pb); + if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR) + return -1; + + if (rv == 1) { + if (file_printf(ms, "%s", rbuf) == -1) { + free(rbuf); + return -1; + } + } + free(rbuf); + return rv; + case FILE_DEFAULT: /* nothing to check */ default: break;