aboutsummaryrefslogtreecommitdiff
path: root/src/funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/funcs.c')
-rw-r--r--src/funcs.c115
1 files changed, 75 insertions, 40 deletions
diff --git a/src/funcs.c b/src/funcs.c
index 0bf92fe1c250..23e7f32e63d2 100644
--- a/src/funcs.c
+++ b/src/funcs.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.104 2019/05/07 02:27:11 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -42,9 +42,7 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $")
#if defined(HAVE_WCTYPE_H)
#include <wctype.h>
#endif
-#if defined(HAVE_LIMITS_H)
#include <limits.h>
-#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)~0)
@@ -107,13 +105,13 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
if (lineno != 0) {
free(ms->o.buf);
ms->o.buf = NULL;
- file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
+ (void)file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
}
if (ms->o.buf && *ms->o.buf)
- file_printf(ms, " ");
- file_vprintf(ms, f, va);
+ (void)file_printf(ms, " ");
+ (void)file_vprintf(ms, f, va);
if (error > 0)
- file_printf(ms, " (%s)", strerror(error));
+ (void)file_printf(ms, " (%s)", strerror(error));
ms->event_flags |= EVENT_HAD_ERR;
ms->error = error;
}
@@ -162,36 +160,70 @@ file_badread(struct magic_set *ms)
#ifndef COMPILE_ONLY
+protected int
+file_separator(struct magic_set *ms)
+{
+ return file_printf(ms, "\n- ");
+}
+
static int
checkdone(struct magic_set *ms, int *rv)
{
if ((ms->flags & MAGIC_CONTINUE) == 0)
return 1;
- if (file_printf(ms, "\n- ") == -1)
+ if (file_separator(ms) == -1)
*rv = -1;
return 0;
}
+protected int
+file_default(struct magic_set *ms, size_t nb)
+{
+ if (ms->flags & MAGIC_MIME) {
+ if ((ms->flags & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/%s",
+ nb ? "octet-stream" : "x-empty") == -1)
+ return -1;
+ return 1;
+ }
+ if (ms->flags & MAGIC_APPLE) {
+ if (file_printf(ms, "UNKNUNKN") == -1)
+ return -1;
+ return 1;
+ }
+ if (ms->flags & MAGIC_EXTENSION) {
+ if (file_printf(ms, "???") == -1)
+ return -1;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * The magic detection functions return:
+ * 1: found
+ * 0: not found
+ * -1: error
+ */
/*ARGSUSED*/
protected int
-file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)),
+file_buffer(struct magic_set *ms, int fd, struct stat *st,
+ const char *inname __attribute__ ((__unused__)),
const void *buf, size_t nb)
{
int m = 0, rv = 0, looks_text = 0;
const char *code = NULL;
const char *code_mime = "binary";
- const char *type = "application/octet-stream";
const char *def = "data";
const char *ftype = NULL;
char *rbuf = NULL;
struct buffer b;
- buffer_init(&b, fd, buf, nb);
+ buffer_init(&b, fd, st, buf, nb);
ms->mode = b.st.st_mode;
if (nb == 0) {
def = "empty";
- type = "application/x-empty";
goto simple;
} else if (nb == 1) {
def = "very short file (no magic)";
@@ -240,6 +272,17 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
}
}
+ /* Check if we have a JSON file */
+ if ((ms->flags & MAGIC_NO_CHECK_JSON) == 0) {
+ m = file_is_json(ms, &b);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try json %d]\n", m);
+ if (m) {
+ if (checkdone(ms, &rv))
+ goto done;
+ }
+ }
+
/* Check if we have a CDF file */
if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
m = file_trycdf(ms, &b);
@@ -268,7 +311,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
rv = file_tryelf(ms, &b);
rbuf = file_pop_buffer(ms, pb);
- if (rv != 1) {
+ if (rv == -1) {
free(rbuf);
rbuf = NULL;
}
@@ -299,27 +342,18 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try ascmagic %d]\n", m);
if (m) {
- if (checkdone(ms, &rv))
- goto done;
+ goto done;
}
}
simple:
/* give up */
- m = 1;
- if (ms->flags & MAGIC_MIME) {
- if ((ms->flags & MAGIC_MIME_TYPE) &&
- file_printf(ms, "%s", type) == -1)
- rv = -1;
- } else if (ms->flags & MAGIC_APPLE) {
- if (file_printf(ms, "UNKNUNKN") == -1)
- rv = -1;
- } else if (ms->flags & MAGIC_EXTENSION) {
- if (file_printf(ms, "???") == -1)
- rv = -1;
- } else {
- if (file_printf(ms, "%s", def) == -1)
- rv = -1;
+ if (m == 0) {
+ m = 1;
+ rv = file_default(ms, nb);
+ if (rv == 0)
+ if (file_printf(ms, "%s", def) == -1)
+ rv = -1;
}
done:
if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {
@@ -364,9 +398,9 @@ file_reset(struct magic_set *ms, int checkloaded)
#define OCTALIFY(n, o) \
/*LINTED*/ \
(void)(*(n)++ = '\\', \
- *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
- *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
- *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
+ *(n)++ = ((CAST(uint32_t, *(o)) >> 6) & 3) + '0', \
+ *(n)++ = ((CAST(uint32_t, *(o)) >> 3) & 7) + '0', \
+ *(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \
(o)++)
protected const char *
@@ -412,9 +446,9 @@ file_getbuffer(struct magic_set *ms)
while (op < eop) {
bytesconsumed = mbrtowc(&nextchar, op,
- (size_t)(eop - op), &state);
- if (bytesconsumed == (size_t)(-1) ||
- bytesconsumed == (size_t)(-2)) {
+ CAST(size_t, eop - op), &state);
+ if (bytesconsumed == CAST(size_t, -1) ||
+ bytesconsumed == CAST(size_t, -2)) {
mb_conv = 0;
break;
}
@@ -437,7 +471,7 @@ file_getbuffer(struct magic_set *ms)
#endif
for (np = ms->o.pbuf, op = ms->o.buf; *op;) {
- if (isprint((unsigned char)*op)) {
+ if (isprint(CAST(unsigned char, *op))) {
*np++ = *op++;
} else {
OCTALIFY(np, op);
@@ -595,12 +629,13 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
* convert string to ascii printable format.
*/
protected char *
-file_printable(char *buf, size_t bufsiz, const char *str)
+file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
{
- char *ptr, *eptr;
- const unsigned char *s = (const unsigned char *)str;
+ char *ptr, *eptr = buf + bufsiz - 1;
+ const unsigned char *s = RCAST(const unsigned char *, str);
+ const unsigned char *es = s + slen;
- for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
+ for (ptr = buf; ptr < eptr && s < es && *s; s++) {
if (isprint(*s)) {
*ptr++ = *s;
continue;