Deleted Added
full compact
softmagic.c (275666) softmagic.c (275698)
1/*
2 * Copyright (c) Ian F. Darwin 1986-1995.
3 * Software written by Ian F. Darwin and others;
4 * maintained 1995-present by Christos Zoulas and others.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 18 unchanged lines hidden (view full) ---

27 */
28/*
29 * softmagic - interpret variable magic from MAGIC
30 */
31
32#include "file.h"
33
34#ifndef lint
1/*
2 * Copyright (c) Ian F. Darwin 1986-1995.
3 * Software written by Ian F. Darwin and others;
4 * maintained 1995-present by Christos Zoulas and others.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 18 unchanged lines hidden (view full) ---

27 */
28/*
29 * softmagic - interpret variable magic from MAGIC
30 */
31
32#include "file.h"
33
34#ifndef lint
35FILE_RCSID("@(#)$File: softmagic.c,v 1.191 2014/06/04 17:36:34 christos Exp $")
35FILE_RCSID("@(#)$File: softmagic.c,v 1.203 2014/12/04 15:22:05 christos Exp $")
36#endif /* lint */
37
38#include "magic.h"
39#include <assert.h>
40#include <string.h>
41#include <ctype.h>
42#include <stdlib.h>
43#include <time.h>
36#endif /* lint */
37
38#include "magic.h"
39#include <assert.h>
40#include <string.h>
41#include <ctype.h>
42#include <stdlib.h>
43#include <time.h>
44#if defined(HAVE_LOCALE_H)
45#include <locale.h>
46#endif
47
44
48
49private int match(struct magic_set *, struct magic *, uint32_t,
45private int match(struct magic_set *, struct magic *, uint32_t,
50 const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
51 int *);
46 const unsigned char *, size_t, size_t, int, int, int, uint16_t,
47 uint16_t *, int *, int *, int *);
52private int mget(struct magic_set *, const unsigned char *,
48private int mget(struct magic_set *, const unsigned char *,
53 struct magic *, size_t, size_t, unsigned int, int, int, int, int, int *,
54 int *, int *);
49 struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t,
50 uint16_t *, int *, int *, int *);
55private int magiccheck(struct magic_set *, struct magic *);
56private int32_t mprint(struct magic_set *, struct magic *);
57private int32_t moffset(struct magic_set *, struct magic *);
58private void mdebug(uint32_t, const char *, size_t);
59private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
60 const unsigned char *, uint32_t, size_t, struct magic *);
61private int mconvert(struct magic_set *, struct magic *, int);
62private int print_sep(struct magic_set *, int);
63private int handle_annotation(struct magic_set *, struct magic *);
64private void cvt_8(union VALUETYPE *, const struct magic *);
65private void cvt_16(union VALUETYPE *, const struct magic *);
66private void cvt_32(union VALUETYPE *, const struct magic *);
67private void cvt_64(union VALUETYPE *, const struct magic *);
68
69#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
70
51private int magiccheck(struct magic_set *, struct magic *);
52private int32_t mprint(struct magic_set *, struct magic *);
53private int32_t moffset(struct magic_set *, struct magic *);
54private void mdebug(uint32_t, const char *, size_t);
55private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
56 const unsigned char *, uint32_t, size_t, struct magic *);
57private int mconvert(struct magic_set *, struct magic *, int);
58private int print_sep(struct magic_set *, int);
59private int handle_annotation(struct magic_set *, struct magic *);
60private void cvt_8(union VALUETYPE *, const struct magic *);
61private void cvt_16(union VALUETYPE *, const struct magic *);
62private void cvt_32(union VALUETYPE *, const struct magic *);
63private void cvt_64(union VALUETYPE *, const struct magic *);
64
65#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
66
71#define MAX_RECURSION_LEVEL 10
72
73/*
74 * softmagic - lookup one file in parsed, in-memory copy of database
75 * Passed the name and FILE * of one file to be typed.
76 */
77/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
78protected int
79file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
67/*
68 * softmagic - lookup one file in parsed, in-memory copy of database
69 * Passed the name and FILE * of one file to be typed.
70 */
71/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
72protected int
73file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
80 size_t level, int mode, int text)
74 uint16_t indir_level, uint16_t *name_count, int mode, int text)
81{
82 struct mlist *ml;
83 int rv, printed_something = 0, need_separator = 0;
75{
76 struct mlist *ml;
77 int rv, printed_something = 0, need_separator = 0;
78 uint16_t nc;
79
80 if (name_count == NULL) {
81 nc = 0;
82 name_count = &nc;
83 }
84
84 for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
85 if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
85 for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
86 if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
86 text, 0, level, &printed_something, &need_separator,
87 NULL)) != 0)
87 text, 0, indir_level, name_count,
88 &printed_something, &need_separator, NULL)) != 0)
88 return rv;
89
90 return 0;
91}
92
93#define FILE_FMTDEBUG
94#ifdef FILE_FMTDEBUG
95#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
96
97private const char * __attribute__((__format_arg__(3)))
98file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
99 const char *file, size_t line)
100{
101 const char *ptr = fmtcheck(m->desc, def);
102 if (ptr == def)
103 file_magerror(ms,
89 return rv;
90
91 return 0;
92}
93
94#define FILE_FMTDEBUG
95#ifdef FILE_FMTDEBUG
96#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
97
98private const char * __attribute__((__format_arg__(3)))
99file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
100 const char *file, size_t line)
101{
102 const char *ptr = fmtcheck(m->desc, def);
103 if (ptr == def)
104 file_magerror(ms,
104 "%s, %zu: format `%s' does not match with `%s'",
105 file, line, m->desc, def);
105 "%s, %" SIZE_T_FORMAT "u: format `%s' does not match"
106 " with `%s'", file, line, m->desc, def);
106 return ptr;
107}
108#else
109#define F(a, b, c) fmtcheck((b)->desc, (c))
110#endif
111
112/*
113 * Go through the whole list, stopping if you find a match. Process all

--- 20 unchanged lines hidden (view full) ---

134 * one, there's no lower-level continuation that may have failed.
135 *
136 * If a continuation matches, we bump the current continuation level
137 * so that higher-level continuations are processed.
138 */
139private int
140match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
141 const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
107 return ptr;
108}
109#else
110#define F(a, b, c) fmtcheck((b)->desc, (c))
111#endif
112
113/*
114 * Go through the whole list, stopping if you find a match. Process all

--- 20 unchanged lines hidden (view full) ---

135 * one, there's no lower-level continuation that may have failed.
136 *
137 * If a continuation matches, we bump the current continuation level
138 * so that higher-level continuations are processed.
139 */
140private int
141match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
142 const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
142 int flip, int recursion_level, int *printed_something, int *need_separator,
143 int *returnval)
143 int flip, uint16_t indir_level, uint16_t *name_count,
144 int *printed_something, int *need_separator, int *returnval)
144{
145 uint32_t magindex = 0;
146 unsigned int cont_level = 0;
147 int returnvalv = 0, e; /* if a match is found it is set to 1*/
148 int firstline = 1; /* a flag to print X\n X\n- X */
149 int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
150
151 if (returnval == NULL)

--- 20 unchanged lines hidden (view full) ---

172 continue; /* Skip to next top-level test*/
173 }
174
175 ms->offset = m->offset;
176 ms->line = m->lineno;
177
178 /* if main entry matches, print it... */
179 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
145{
146 uint32_t magindex = 0;
147 unsigned int cont_level = 0;
148 int returnvalv = 0, e; /* if a match is found it is set to 1*/
149 int firstline = 1; /* a flag to print X\n X\n- X */
150 int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
151
152 if (returnval == NULL)

--- 20 unchanged lines hidden (view full) ---

173 continue; /* Skip to next top-level test*/
174 }
175
176 ms->offset = m->offset;
177 ms->line = m->lineno;
178
179 /* if main entry matches, print it... */
180 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
180 flip, recursion_level + 1, printed_something,
181 need_separator, returnval)) {
181 flip, indir_level, name_count,
182 printed_something, need_separator, returnval)) {
182 case -1:
183 return -1;
184 case 0:
185 flush = m->reln != '!';
186 break;
187 default:
188 if (m->type == FILE_INDIRECT)
189 *returnval = 1;

--- 43 unchanged lines hidden (view full) ---

233 return -1;
234
235 ms->c.li[cont_level].off = moffset(ms, m);
236
237 /* and any continuations that match */
238 if (file_check_mem(ms, ++cont_level) == -1)
239 return -1;
240
183 case -1:
184 return -1;
185 case 0:
186 flush = m->reln != '!';
187 break;
188 default:
189 if (m->type == FILE_INDIRECT)
190 *returnval = 1;

--- 43 unchanged lines hidden (view full) ---

234 return -1;
235
236 ms->c.li[cont_level].off = moffset(ms, m);
237
238 /* and any continuations that match */
239 if (file_check_mem(ms, ++cont_level) == -1)
240 return -1;
241
241 while (++magindex < nmagic &&
242 magic[magindex].cont_level != 0) {
243 m = &magic[magindex];
242 while (magindex + 1 < nmagic &&
243 magic[magindex + 1].cont_level != 0) {
244 m = &magic[++magindex];
244 ms->line = m->lineno; /* for messages */
245
246 if (cont_level < m->cont_level)
247 continue;
248 if (cont_level > m->cont_level) {
249 /*
250 * We're at the end of the level
251 * "cont_level" continuations.

--- 9 unchanged lines hidden (view full) ---

261#ifdef ENABLE_CONDITIONALS
262 if (m->cond == COND_ELSE ||
263 m->cond == COND_ELIF) {
264 if (ms->c.li[cont_level].last_match == 1)
265 continue;
266 }
267#endif
268 switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
245 ms->line = m->lineno; /* for messages */
246
247 if (cont_level < m->cont_level)
248 continue;
249 if (cont_level > m->cont_level) {
250 /*
251 * We're at the end of the level
252 * "cont_level" continuations.

--- 9 unchanged lines hidden (view full) ---

262#ifdef ENABLE_CONDITIONALS
263 if (m->cond == COND_ELSE ||
264 m->cond == COND_ELIF) {
265 if (ms->c.li[cont_level].last_match == 1)
266 continue;
267 }
268#endif
269 switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
269 text, flip, recursion_level + 1, printed_something,
270 need_separator, returnval)) {
270 text, flip, indir_level, name_count,
271 printed_something, need_separator, returnval)) {
271 case -1:
272 return -1;
273 case 0:
274 if (m->reln != '!')
275 continue;
276 flush = 1;
277 break;
278 default:

--- 119 unchanged lines hidden (view full) ---

398 if ((copy = malloc(len + 1)) == NULL)
399 return NULL;
400 (void)memcpy(copy, str, len);
401 copy[len] = '\0';
402 return copy;
403}
404#endif /* HAVE_STRNDUP */
405
272 case -1:
273 return -1;
274 case 0:
275 if (m->reln != '!')
276 continue;
277 flush = 1;
278 break;
279 default:

--- 119 unchanged lines hidden (view full) ---

399 if ((copy = malloc(len + 1)) == NULL)
400 return NULL;
401 (void)memcpy(copy, str, len);
402 copy[len] = '\0';
403 return copy;
404}
405#endif /* HAVE_STRNDUP */
406
407static char *
408printable(char *buf, size_t bufsiz, const char *str)
409{
410 char *ptr, *eptr;
411 const unsigned char *s = (const unsigned char *)str;
412
413 for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
414 if (isprint(*s)) {
415 *ptr++ = *s;
416 continue;
417 }
418 if (ptr >= eptr + 4)
419 break;
420 *ptr++ = '\\';
421 *ptr++ = ((*s >> 6) & 7) + '0';
422 *ptr++ = ((*s >> 3) & 7) + '0';
423 *ptr++ = ((*s >> 0) & 7) + '0';
424 }
425 *ptr = '\0';
426 return buf;
427}
428
406private int32_t
407mprint(struct magic_set *ms, struct magic *m)
408{
409 uint64_t v;
410 float vf;
411 double vd;
412 int64_t t = 0;
413 char buf[128], tbuf[26];

--- 90 unchanged lines hidden (view full) ---

504 case FILE_BESTRING16:
505 case FILE_LESTRING16:
506 if (m->reln == '=' || m->reln == '!') {
507 if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1)
508 return -1;
509 t = ms->offset + m->vallen;
510 }
511 else {
429private int32_t
430mprint(struct magic_set *ms, struct magic *m)
431{
432 uint64_t v;
433 float vf;
434 double vd;
435 int64_t t = 0;
436 char buf[128], tbuf[26];

--- 90 unchanged lines hidden (view full) ---

527 case FILE_BESTRING16:
528 case FILE_LESTRING16:
529 if (m->reln == '=' || m->reln == '!') {
530 if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1)
531 return -1;
532 t = ms->offset + m->vallen;
533 }
534 else {
535 char sbuf[512];
512 char *str = p->s;
513
514 /* compute t before we mangle the string? */
515 t = ms->offset + strlen(str);
516
517 if (*m->value.s == '\0')
518 str[strcspn(str, "\n")] = '\0';
519

--- 5 unchanged lines hidden (view full) ---

525 while (*last)
526 last++;
527 --last;
528 while (isspace((unsigned char)*last))
529 last--;
530 *++last = '\0';
531 }
532
536 char *str = p->s;
537
538 /* compute t before we mangle the string? */
539 t = ms->offset + strlen(str);
540
541 if (*m->value.s == '\0')
542 str[strcspn(str, "\n")] = '\0';
543

--- 5 unchanged lines hidden (view full) ---

549 while (*last)
550 last++;
551 --last;
552 while (isspace((unsigned char)*last))
553 last--;
554 *++last = '\0';
555 }
556
533 if (file_printf(ms, F(ms, m, "%s"), str) == -1)
557 if (file_printf(ms, F(ms, m, "%s"),
558 printable(sbuf, sizeof(sbuf), str)) == -1)
534 return -1;
535
536 if (m->type == FILE_PSTRING)
537 t += file_pstring_length_size(m);
538 }
539 break;
540
541 case FILE_DATE:

--- 399 unchanged lines hidden (view full) ---

941 /* Null terminate and eat *trailing* return */
942 p->s[sizeof(p->s) - 1] = '\0';
943 return 1;
944 }
945 case FILE_PSTRING: {
946 size_t sz = file_pstring_length_size(m);
947 char *ptr1 = p->s, *ptr2 = ptr1 + sz;
948 size_t len = file_pstring_get_length(m, ptr1);
559 return -1;
560
561 if (m->type == FILE_PSTRING)
562 t += file_pstring_length_size(m);
563 }
564 break;
565
566 case FILE_DATE:

--- 399 unchanged lines hidden (view full) ---

966 /* Null terminate and eat *trailing* return */
967 p->s[sizeof(p->s) - 1] = '\0';
968 return 1;
969 }
970 case FILE_PSTRING: {
971 size_t sz = file_pstring_length_size(m);
972 char *ptr1 = p->s, *ptr2 = ptr1 + sz;
973 size_t len = file_pstring_get_length(m, ptr1);
949 if (len >= sizeof(p->s)) {
974 sz = sizeof(p->s) - sz; /* maximum length of string */
975 if (len >= sz) {
950 /*
951 * The size of the pascal string length (sz)
952 * is 1, 2, or 4. We need at least 1 byte for NUL
953 * termination, but we've already truncated the
954 * string by p->s, so we need to deduct sz.
976 /*
977 * The size of the pascal string length (sz)
978 * is 1, 2, or 4. We need at least 1 byte for NUL
979 * termination, but we've already truncated the
980 * string by p->s, so we need to deduct sz.
981 * Because we can use one of the bytes of the length
982 * after we shifted as NUL termination.
955 */
983 */
956 len = sizeof(p->s) - sz;
984 len = sz;
957 }
958 while (len--)
959 *ptr1++ = *ptr2++;
960 *ptr1 = '\0';
961 return 1;
962 }
963 case FILE_BESHORT:
964 p->h = (short)((p->hs[0]<<8)|(p->hs[1]));

--- 93 unchanged lines hidden (view full) ---

1058 return 0;
1059 }
1060}
1061
1062
1063private void
1064mdebug(uint32_t offset, const char *str, size_t len)
1065{
985 }
986 while (len--)
987 *ptr1++ = *ptr2++;
988 *ptr1 = '\0';
989 return 1;
990 }
991 case FILE_BESHORT:
992 p->h = (short)((p->hs[0]<<8)|(p->hs[1]));

--- 93 unchanged lines hidden (view full) ---

1086 return 0;
1087 }
1088}
1089
1090
1091private void
1092mdebug(uint32_t offset, const char *str, size_t len)
1093{
1066 (void) fprintf(stderr, "mget/%zu @%d: ", len, offset);
1094 (void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset);
1067 file_showstr(stderr, str, len);
1068 (void) fputc('\n', stderr);
1069 (void) fputc('\n', stderr);
1070}
1071
1072private int
1073mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
1074 const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)

--- 113 unchanged lines hidden (view full) ---

1188 (void)memset(((char *)(void *)p) + nbytes, '\0',
1189 sizeof(*p) - nbytes);
1190 return 0;
1191}
1192
1193private int
1194mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
1195 size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
1095 file_showstr(stderr, str, len);
1096 (void) fputc('\n', stderr);
1097 (void) fputc('\n', stderr);
1098}
1099
1100private int
1101mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
1102 const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)

--- 113 unchanged lines hidden (view full) ---

1216 (void)memset(((char *)(void *)p) + nbytes, '\0',
1217 sizeof(*p) - nbytes);
1218 return 0;
1219}
1220
1221private int
1222mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
1223 size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
1196 int flip, int recursion_level, int *printed_something,
1197 int *need_separator, int *returnval)
1224 int flip, uint16_t indir_level, uint16_t *name_count,
1225 int *printed_something, int *need_separator, int *returnval)
1198{
1199 uint32_t offset = ms->offset;
1200 uint32_t lhs;
1201 file_pushbuf_t *pb;
1202 int rv, oneed_separator, in_type;
1203 char *rbuf;
1204 union VALUETYPE *p = &ms->ms_value;
1205 struct mlist ml;
1206
1226{
1227 uint32_t offset = ms->offset;
1228 uint32_t lhs;
1229 file_pushbuf_t *pb;
1230 int rv, oneed_separator, in_type;
1231 char *rbuf;
1232 union VALUETYPE *p = &ms->ms_value;
1233 struct mlist ml;
1234
1207 if (recursion_level >= MAX_RECURSION_LEVEL) {
1208 file_error(ms, 0, "recursion nesting exceeded");
1235 if (indir_level >= ms->indir_max) {
1236 file_error(ms, 0, "indirect recursion nesting (%hu) exceeded",
1237 indir_level);
1209 return -1;
1210 }
1211
1238 return -1;
1239 }
1240
1241 if (*name_count >= ms->name_max) {
1242 file_error(ms, 0, "name use count (%hu) exceeded",
1243 *name_count);
1244 return -1;
1245 }
1246
1212 if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
1213 (uint32_t)nbytes, m) == -1)
1214 return -1;
1215
1216 if ((ms->flags & MAGIC_DEBUG) != 0) {
1247 if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
1248 (uint32_t)nbytes, m) == -1)
1249 return -1;
1250
1251 if ((ms->flags & MAGIC_DEBUG) != 0) {
1217 fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
1218 "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
1252 fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%"
1253 SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
1254 "u, il=%hu, nc=%hu)\n",
1255 m->type, m->flag, offset, o, nbytes,
1256 indir_level, *name_count);
1219 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
1220#ifndef COMPILE_ONLY
1221 file_mdump(m);
1222#endif
1223 }
1224
1225 if (m->flag & INDIR) {
1226 int off = m->in_offset;

--- 424 unchanged lines hidden (view full) ---

1651
1652 if (nbytes < offset)
1653 return 0;
1654
1655 if ((pb = file_push_buffer(ms)) == NULL)
1656 return -1;
1657
1658 rv = file_softmagic(ms, s + offset, nbytes - offset,
1257 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
1258#ifndef COMPILE_ONLY
1259 file_mdump(m);
1260#endif
1261 }
1262
1263 if (m->flag & INDIR) {
1264 int off = m->in_offset;

--- 424 unchanged lines hidden (view full) ---

1689
1690 if (nbytes < offset)
1691 return 0;
1692
1693 if ((pb = file_push_buffer(ms)) == NULL)
1694 return -1;
1695
1696 rv = file_softmagic(ms, s + offset, nbytes - offset,
1659 recursion_level, BINTEST, text);
1697 indir_level + 1, name_count, BINTEST, text);
1660
1661 if ((ms->flags & MAGIC_DEBUG) != 0)
1662 fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
1663
1664 rbuf = file_pop_buffer(ms, pb);
1665 if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
1666 return -1;
1667

--- 18 unchanged lines hidden (view full) ---

1686 if (*rbuf == '^') {
1687 rbuf++;
1688 flip = !flip;
1689 }
1690 if (file_magicfind(ms, rbuf, &ml) == -1) {
1691 file_error(ms, 0, "cannot find entry `%s'", rbuf);
1692 return -1;
1693 }
1698
1699 if ((ms->flags & MAGIC_DEBUG) != 0)
1700 fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
1701
1702 rbuf = file_pop_buffer(ms, pb);
1703 if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
1704 return -1;
1705

--- 18 unchanged lines hidden (view full) ---

1724 if (*rbuf == '^') {
1725 rbuf++;
1726 flip = !flip;
1727 }
1728 if (file_magicfind(ms, rbuf, &ml) == -1) {
1729 file_error(ms, 0, "cannot find entry `%s'", rbuf);
1730 return -1;
1731 }
1694
1732 (*name_count)++;
1695 oneed_separator = *need_separator;
1696 if (m->flag & NOSPACE)
1697 *need_separator = 0;
1698 rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
1733 oneed_separator = *need_separator;
1734 if (m->flag & NOSPACE)
1735 *need_separator = 0;
1736 rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
1699 mode, text, flip, recursion_level, printed_something,
1700 need_separator, returnval);
1737 mode, text, flip, indir_level, name_count,
1738 printed_something, need_separator, returnval);
1701 if (rv != 1)
1702 *need_separator = oneed_separator;
1703 return rv;
1704
1705 case FILE_NAME:
1706 if (file_printf(ms, "%s", m->desc) == -1)
1707 return -1;
1708 return 1;

--- 238 unchanged lines hidden (view full) ---

1947 break;
1948 }
1949 }
1950 break;
1951 }
1952 case FILE_REGEX: {
1953 int rc;
1954 file_regex_t rx;
1739 if (rv != 1)
1740 *need_separator = oneed_separator;
1741 return rv;
1742
1743 case FILE_NAME:
1744 if (file_printf(ms, "%s", m->desc) == -1)
1745 return -1;
1746 return 1;

--- 238 unchanged lines hidden (view full) ---

1985 break;
1986 }
1987 }
1988 break;
1989 }
1990 case FILE_REGEX: {
1991 int rc;
1992 file_regex_t rx;
1993 const char *search;
1955
1956 if (ms->search.s == NULL)
1957 return 0;
1958
1959 l = 0;
1960 rc = file_regcomp(&rx, m->value.s,
1961 REG_EXTENDED|REG_NEWLINE|
1962 ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
1963 if (rc) {
1964 file_regerror(&rx, rc, ms);
1965 v = (uint64_t)-1;
1966 } else {
1967 regmatch_t pmatch[1];
1968 size_t slen = ms->search.s_len;
1969#ifndef REG_STARTEND
1970#define REG_STARTEND 0
1994
1995 if (ms->search.s == NULL)
1996 return 0;
1997
1998 l = 0;
1999 rc = file_regcomp(&rx, m->value.s,
2000 REG_EXTENDED|REG_NEWLINE|
2001 ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
2002 if (rc) {
2003 file_regerror(&rx, rc, ms);
2004 v = (uint64_t)-1;
2005 } else {
2006 regmatch_t pmatch[1];
2007 size_t slen = ms->search.s_len;
2008#ifndef REG_STARTEND
2009#define REG_STARTEND 0
1971 char c;
1972 if (slen != 0)
1973 slen--;
1974 c = ms->search.s[slen];
1975 ((char *)(intptr_t)ms->search.s)[slen] = '\0';
2010 char *copy;
2011 if (slen != 0) {
2012 copy = malloc(slen);
2013 if (copy == NULL) {
2014 file_error(ms, errno,
2015 "can't allocate %" SIZE_T_FORMAT "u bytes",
2016 slen);
2017 return -1;
2018 }
2019 memcpy(copy, ms->search.s, slen);
2020 copy[--slen] = '\0';
2021 search = copy;
2022 } else {
2023 search = ms->search.s;
2024 copy = NULL;
2025 }
1976#else
2026#else
2027 search = ms->search.s;
1977 pmatch[0].rm_so = 0;
1978 pmatch[0].rm_eo = slen;
1979#endif
2028 pmatch[0].rm_so = 0;
2029 pmatch[0].rm_eo = slen;
2030#endif
1980 rc = file_regexec(&rx, (const char *)ms->search.s,
2031 rc = file_regexec(&rx, (const char *)search,
1981 1, pmatch, REG_STARTEND);
1982#if REG_STARTEND == 0
2032 1, pmatch, REG_STARTEND);
2033#if REG_STARTEND == 0
1983 ((char *)(intptr_t)ms->search.s)[l] = c;
2034 free(copy);
1984#endif
1985 switch (rc) {
1986 case 0:
1987 ms->search.s += (int)pmatch[0].rm_so;
1988 ms->search.offset += (size_t)pmatch[0].rm_so;
1989 ms->search.rm_len =
1990 (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
1991 v = 0;

--- 146 unchanged lines hidden ---
2035#endif
2036 switch (rc) {
2037 case 0:
2038 ms->search.s += (int)pmatch[0].rm_so;
2039 ms->search.offset += (size_t)pmatch[0].rm_so;
2040 ms->search.rm_len =
2041 (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
2042 v = 0;

--- 146 unchanged lines hidden ---