*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.155 2014/10/11 15:03:16 christos Exp $
+ * @(#)$File: file.h,v 1.156 2014/11/23 13:54:27 christos Exp $
*/
#ifndef __file_h__
protected void file_regfree(file_regex_t *);
protected void file_regerror(file_regex_t *, int, struct magic_set *);
+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;
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.73 2014/09/10 18:41:51 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.74 2014/11/23 13:54:27 christos Exp $")
#endif /* lint */
#include "magic.h"
file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
errmsg);
}
+
+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;
+}
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.197 2014/11/11 17:48:23 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.198 2014/11/23 13:54:27 christos Exp $")
#endif /* lint */
#include "magic.h"
private void cvt_64(union VALUETYPE *, const struct magic *);
#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
+
+#define MAX_RECURSION_LEVEL 10
+
/*
* softmagic - lookup one file in parsed, in-memory copy of database
* Passed the name and FILE * of one file to be typed.
int flip, int recursion_level, int *printed_something,
int *need_separator, int *returnval)
{
- uint32_t soffset, offset = ms->offset;
+ uint32_t offset = ms->offset;
uint32_t lhs;
+ file_pushbuf_t *pb;
int rv, oneed_separator, in_type;
- char *sbuf, *rbuf;
+ char *rbuf;
union VALUETYPE *p = &ms->ms_value;
struct mlist ml;
- if (recursion_level >= 20) {
+ if (recursion_level >= MAX_RECURSION_LEVEL) {
file_error(ms, 0, "recursion nesting exceeded");
return -1;
}
case FILE_INDIRECT:
if (offset == 0)
return 0;
+
if (nbytes < offset)
return 0;
- sbuf = ms->o.buf;
- soffset = ms->offset;
- ms->o.buf = NULL;
- ms->offset = 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 = ms->o.buf;
- ms->o.buf = sbuf;
- ms->offset = soffset;
+
+ rbuf = file_pop_buffer(ms, pb);
+ if (rbuf == NULL)
+ return -1;
+
if (rv == 1) {
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
file_printf(ms, F(ms, m, "%u"), offset) == -1) {
case FILE_USE:
if (nbytes < offset)
return 0;
- sbuf = m->value.s;
- if (*sbuf == '^') {
- sbuf++;
+ rbuf = m->value.s;
+ if (*rbuf == '^') {
+ rbuf++;
flip = !flip;
}
- if (file_magicfind(ms, sbuf, &ml) == -1) {
- file_error(ms, 0, "cannot find entry `%s'", sbuf);
+ if (file_magicfind(ms, rbuf, &ml) == -1) {
+ file_error(ms, 0, "cannot find entry `%s'", rbuf);
return -1;
}