Coverage Report

Created: 2023-09-25 06:40

/src/file/src/softmagic.c
Line
Count
Source (jump to first uncovered line)
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:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice immediately at the beginning of the file, without modification,
11
 *    this list of conditions, and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
/*
29
 * softmagic - interpret variable magic from MAGIC
30
 */
31
32
#include "file.h"
33
34
#ifndef lint
35
FILE_RCSID("@(#)$File: softmagic.c,v 1.345 2023/07/02 12:48:39 christos Exp $")
36
#endif  /* lint */
37
38
#include "magic.h"
39
#include <assert.h>
40
#include <math.h>
41
#include <string.h>
42
#include <ctype.h>
43
#include <stdlib.h>
44
#include <limits.h>
45
#include <time.h>
46
#include "der.h"
47
48
file_private int match(struct magic_set *, struct magic *, file_regex_t **, size_t,
49
    const struct buffer *, size_t, int, int, int, uint16_t *,
50
    uint16_t *, int *, int *, int *, int *, int *);
51
file_private int mget(struct magic_set *, struct magic *, const struct buffer *,
52
    const unsigned char *, size_t,
53
    size_t, unsigned int, int, int, int, uint16_t *,
54
    uint16_t *, int *, int *, int *, int *, int *);
55
file_private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
56
    const struct buffer *, size_t, unsigned int);
57
file_private int magiccheck(struct magic_set *, struct magic *, file_regex_t **);
58
file_private int mprint(struct magic_set *, struct magic *);
59
file_private int moffset(struct magic_set *, struct magic *, const struct buffer *,
60
    int32_t *);
61
file_private void mdebug(uint32_t, const char *, size_t);
62
file_private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
63
    const unsigned char *, uint32_t, size_t, struct magic *);
64
file_private int mconvert(struct magic_set *, struct magic *, int);
65
file_private int print_sep(struct magic_set *, int);
66
file_private int handle_annotation(struct magic_set *, struct magic *, int);
67
file_private int cvt_8(union VALUETYPE *, const struct magic *);
68
file_private int cvt_16(union VALUETYPE *, const struct magic *);
69
file_private int cvt_32(union VALUETYPE *, const struct magic *);
70
file_private int cvt_64(union VALUETYPE *, const struct magic *);
71
72
74.0M
#define OFFSET_OOB(n, o, i) ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o)))
73
106
#define BE64(p) ( \
74
106
    (CAST(uint64_t, (p)->hq[0])<<56)| \
75
106
    (CAST(uint64_t, (p)->hq[1])<<48)| \
76
106
    (CAST(uint64_t, (p)->hq[2])<<40)| \
77
106
    (CAST(uint64_t, (p)->hq[3])<<32)| \
78
106
    (CAST(uint64_t, (p)->hq[4])<<24)| \
79
106
    (CAST(uint64_t, (p)->hq[5])<<16)| \
80
106
    (CAST(uint64_t, (p)->hq[6])<<8)| \
81
106
    (CAST(uint64_t, (p)->hq[7])))
82
139
#define LE64(p) ( \
83
139
    (CAST(uint64_t, (p)->hq[7])<<56)| \
84
139
    (CAST(uint64_t, (p)->hq[6])<<48)| \
85
139
    (CAST(uint64_t, (p)->hq[5])<<40)| \
86
139
    (CAST(uint64_t, (p)->hq[4])<<32)| \
87
139
    (CAST(uint64_t, (p)->hq[3])<<24)| \
88
139
    (CAST(uint64_t, (p)->hq[2])<<16)| \
89
139
    (CAST(uint64_t, (p)->hq[1])<<8)| \
90
139
    (CAST(uint64_t, (p)->hq[0])))
91
40.6k
#define LE32(p) ( \
92
40.6k
    (CAST(uint32_t, (p)->hl[3])<<24)| \
93
40.6k
    (CAST(uint32_t, (p)->hl[2])<<16)| \
94
40.6k
    (CAST(uint32_t, (p)->hl[1])<<8)| \
95
40.6k
    (CAST(uint32_t, (p)->hl[0])))
96
4.77k
#define BE32(p) ( \
97
4.77k
    (CAST(uint32_t, (p)->hl[0])<<24)| \
98
4.77k
    (CAST(uint32_t, (p)->hl[1])<<16)| \
99
4.77k
    (CAST(uint32_t, (p)->hl[2])<<8)| \
100
4.77k
    (CAST(uint32_t, (p)->hl[3])))
101
#define ME32(p) ( \
102
    (CAST(uint32_t, (p)->hl[1])<<24)| \
103
    (CAST(uint32_t, (p)->hl[0])<<16)| \
104
    (CAST(uint32_t, (p)->hl[3])<<8)| \
105
    (CAST(uint32_t, (p)->hl[2])))
106
107
#define BE16(p) ((CAST(uint16_t, (p)->hs[0])<<8)|(CAST(uint16_t, (p)->hs[1])))
108
#define LE16(p) ((CAST(uint16_t, (p)->hs[1])<<8)|(CAST(uint16_t, (p)->hs[0])))
109
89.0k
#define SEXT(s,v,p) ((s) ? \
110
89.0k
  CAST(intmax_t, CAST(int##v##_t, p)) : \
111
89.0k
  CAST(intmax_t, CAST(uint##v##_t, p)))
112
113
/*
114
 * softmagic - lookup one file in parsed, in-memory copy of database
115
 * Passed the name and FILE * of one file to be typed.
116
 */
117
/*ARGSUSED1*/   /* nbytes passed for regularity, maybe need later */
118
file_protected int
119
file_softmagic(struct magic_set *ms, const struct buffer *b,
120
    uint16_t *indir_count, uint16_t *name_count, int mode, int text)
121
11.2k
{
122
11.2k
  struct mlist *ml;
123
11.2k
  int rv = 0, printed_something = 0, need_separator = 0, firstline = 1;
124
11.2k
  uint16_t nc, ic;
125
126
11.2k
  if (name_count == NULL) {
127
11.2k
    nc = 0;
128
11.2k
    name_count = &nc;
129
11.2k
  }
130
11.2k
  if (indir_count == NULL) {
131
11.2k
    ic = 0;
132
11.2k
    indir_count = &ic;
133
11.2k
  }
134
135
22.4k
  for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) {
136
11.2k
    int ret = match(ms, ml->magic, ml->magic_rxcomp, ml->nmagic, b,
137
11.2k
        0, mode, text, 0, indir_count, name_count,
138
11.2k
        &printed_something, &need_separator, &firstline,
139
11.2k
        NULL, NULL);
140
11.2k
    switch (ret) {
141
79
    case -1:
142
79
      return ret;
143
3.74k
    case 0:
144
3.74k
      continue;
145
7.45k
    default:
146
7.45k
      if ((ms->flags & MAGIC_CONTINUE) == 0)
147
0
        return ret;
148
7.45k
      rv = ret;
149
7.45k
      break;
150
11.2k
    }
151
11.2k
  }
152
153
11.2k
  return rv;
154
11.2k
}
155
156
#define FILE_FMTDEBUG
157
#ifdef FILE_FMTDEBUG
158
117k
#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
159
160
file_private const char * __attribute__((__format_arg__(3)))
161
file_fmtcheck(struct magic_set *ms, const char *desc, const char *def,
162
  const char *file, size_t line)
163
117k
{
164
117k
  const char *ptr;
165
166
117k
  if (strchr(desc, '%') == NULL)
167
84.9k
    return desc;
168
169
32.1k
  ptr = fmtcheck(desc, def);
170
32.1k
  if (ptr == def)
171
0
    file_magerror(ms,
172
0
        "%s, %" SIZE_T_FORMAT "u: format `%s' does not match"
173
0
        " with `%s'", file, line, desc, def);
174
32.1k
  return ptr;
175
117k
}
176
#else
177
#define F(a, b, c) fmtcheck((b), (c))
178
#endif
179
180
/*
181
 * Go through the whole list, stopping if you find a match.  Process all
182
 * the continuations of that match before returning.
183
 *
184
 * We support multi-level continuations:
185
 *
186
 *  At any time when processing a successful top-level match, there is a
187
 *  current continuation level; it represents the level of the last
188
 *  successfully matched continuation.
189
 *
190
 *  Continuations above that level are skipped as, if we see one, it
191
 *  means that the continuation that controls them - i.e, the
192
 *  lower-level continuation preceding them - failed to match.
193
 *
194
 *  Continuations below that level are processed as, if we see one,
195
 *  it means we've finished processing or skipping higher-level
196
 *  continuations under the control of a successful or unsuccessful
197
 *  lower-level continuation, and are now seeing the next lower-level
198
 *  continuation and should process it.  The current continuation
199
 *  level reverts to the level of the one we're seeing.
200
 *
201
 *  Continuations at the current level are processed as, if we see
202
 *  one, there's no lower-level continuation that may have failed.
203
 *
204
 *  If a continuation matches, we bump the current continuation level
205
 *  so that higher-level continuations are processed.
206
 */
207
file_private int
208
match(struct magic_set *ms, struct magic *magic, file_regex_t **magic_rxcomp,
209
    size_t nmagic, const struct buffer *b, size_t offset, int mode, int text,
210
    int flip, uint16_t *indir_count, uint16_t *name_count,
211
    int *printed_something, int *need_separator, int *firstline,
212
    int *returnval, int *found_match)
213
69.6k
{
214
69.6k
  uint32_t magindex = 0;
215
69.6k
  unsigned int cont_level = 0;
216
69.6k
  int found_matchv = 0; /* if a match is found it is set to 1*/
217
69.6k
  int returnvalv = 0, e;
218
69.6k
  struct buffer bb;
219
69.6k
  int print = (ms->flags & MAGIC_NODESC) == 0;
220
221
  /*
222
   * returnval can be 0 if a match is found, but there was no
223
   * annotation to be printed.
224
   */
225
69.6k
  if (returnval == NULL)
226
25.0k
    returnval = &returnvalv;
227
69.6k
  if (found_match == NULL)
228
25.0k
    found_match = &found_matchv;
229
230
69.6k
  if (file_check_mem(ms, cont_level) == -1)
231
0
    return -1;
232
233
88.9M
  for (magindex = 0; magindex < nmagic; magindex++) {
234
88.8M
    int flush = 0;
235
88.8M
    struct magic *m = &magic[magindex];
236
88.8M
    file_regex_t **m_rxcomp = &magic_rxcomp[magindex];
237
238
88.8M
    if (m->type != FILE_NAME)
239
88.8M
    if ((IS_STRING(m->type) &&
240
88.8M
#define FLT (STRING_BINTEST | STRING_TEXTTEST)
241
88.8M
         ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
242
62.8M
          (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
243
88.8M
        (m->flag & mode) != mode) {
244
88.6M
flush:
245
      /* Skip sub-tests */
246
401M
      while (magindex < nmagic - 1 &&
247
401M
          magic[magindex + 1].cont_level != 0)
248
313M
        magindex++;
249
88.6M
      cont_level = 0;
250
88.6M
      continue; /* Skip to next top-level test*/
251
14.1M
    }
252
253
74.7M
    if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
254
49.5k
      goto flush;
255
74.6M
    ms->line = m->lineno;
256
257
    /* if main entry matches, print it... */
258
74.6M
    switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
259
74.6M
        bb.flen, offset, cont_level,
260
74.6M
        mode, text, flip, indir_count, name_count,
261
74.6M
        printed_something, need_separator, firstline, returnval,
262
74.6M
        found_match))
263
74.6M
    {
264
335
    case -1:
265
335
      return -1;
266
10.9M
    case 0:
267
10.9M
      flush = m->reln != '!';
268
10.9M
      break;
269
63.7M
    default:
270
63.7M
      if (m->type == FILE_INDIRECT) {
271
0
        *found_match = 1;
272
0
        *returnval = 1;
273
0
      }
274
275
63.7M
      switch (magiccheck(ms, m, m_rxcomp)) {
276
0
      case -1:
277
0
        return -1;
278
63.4M
      case 0:
279
63.4M
        flush++;
280
63.4M
        break;
281
291k
      default:
282
291k
        flush = 0;
283
291k
        break;
284
63.7M
      }
285
63.7M
      break;
286
74.6M
    }
287
74.6M
    if (flush) {
288
      /*
289
       * main entry didn't match,
290
       * flush its continuations
291
       */
292
74.3M
      goto flush;
293
74.3M
    }
294
295
291k
    if ((e = handle_annotation(ms, m, *firstline)) != 0)
296
0
    {
297
0
      *found_match = 1;
298
0
      *need_separator = 1;
299
0
      *printed_something = 1;
300
0
      *returnval = 1;
301
0
      *firstline = 0;
302
0
      return e;
303
0
    }
304
305
    /*
306
     * If we are going to print something, we'll need to print
307
     * a blank before we print something else.
308
     */
309
291k
    if (*m->desc) {
310
23.9k
      *found_match = 1;
311
23.9k
      if (print) {
312
23.9k
        *returnval = 1;
313
23.9k
        *need_separator = 1;
314
23.9k
        *printed_something = 1;
315
23.9k
        if (print_sep(ms, *firstline) == -1)
316
0
          return -1;
317
23.9k
        if (mprint(ms, m) == -1)
318
0
          return -1;
319
23.9k
      }
320
23.9k
    }
321
322
291k
    switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
323
19.6k
    case -1:
324
19.6k
    case 0:
325
19.6k
      goto flush;
326
272k
    default:
327
272k
      break;
328
291k
    }
329
330
    /* and any continuations that match */
331
272k
    if (file_check_mem(ms, ++cont_level) == -1)
332
0
      return -1;
333
334
4.44M
    while (magindex + 1 < nmagic &&
335
4.44M
        magic[magindex + 1].cont_level != 0) {
336
4.17M
      m = &magic[++magindex];
337
4.17M
      m_rxcomp = &magic_rxcomp[magindex];
338
4.17M
      ms->line = m->lineno; /* for messages */
339
340
4.17M
      if (cont_level < m->cont_level)
341
3.03M
        continue;
342
1.14M
      if (cont_level > m->cont_level) {
343
        /*
344
         * We're at the end of the level
345
         * "cont_level" continuations.
346
         */
347
92.6k
        cont_level = m->cont_level;
348
92.6k
      }
349
1.14M
      if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
350
119
        goto flush;
351
1.14M
      if (m->flag & OFFADD) {
352
81.3k
        if (cont_level == 0) {
353
0
          if ((ms->flags & MAGIC_DEBUG) != 0)
354
0
            fprintf(stderr,
355
0
                "direct *zero*"
356
0
                " cont_level\n");
357
0
          return 0;
358
0
        }
359
81.3k
        ms->offset +=
360
81.3k
            ms->c.li[cont_level - 1].off;
361
81.3k
      }
362
363
1.14M
#ifdef ENABLE_CONDITIONALS
364
1.14M
      if (m->cond == COND_ELSE ||
365
1.14M
          m->cond == COND_ELIF) {
366
0
        if (ms->c.li[cont_level].last_match == 1)
367
0
          continue;
368
0
      }
369
1.14M
#endif
370
1.14M
      switch (mget(ms, m, b, CAST(const unsigned char *,
371
1.14M
          bb.fbuf), bb.flen, offset,
372
1.14M
          cont_level, mode, text, flip, indir_count,
373
1.14M
          name_count, printed_something, need_separator,
374
1.14M
          firstline, returnval, found_match)) {
375
1.46k
      case -1:
376
1.46k
        return -1;
377
62.8k
      case 0:
378
62.8k
        if (m->reln != '!')
379
60.8k
          continue;
380
1.93k
        flush = 1;
381
1.93k
        break;
382
1.07M
      default:
383
1.07M
        if (m->type == FILE_INDIRECT) {
384
10.2k
          *found_match = 1;
385
10.2k
          *returnval = 1;
386
10.2k
        }
387
1.07M
        flush = 0;
388
1.07M
        break;
389
1.14M
      }
390
391
1.07M
      switch (flush ? 1 : magiccheck(ms, m, m_rxcomp)) {
392
0
      case -1:
393
0
        return -1;
394
831k
      case 0:
395
831k
#ifdef ENABLE_CONDITIONALS
396
831k
        ms->c.li[cont_level].last_match = 0;
397
831k
#endif
398
831k
        break;
399
248k
      default:
400
248k
#ifdef ENABLE_CONDITIONALS
401
248k
        ms->c.li[cont_level].last_match = 1;
402
248k
#endif
403
248k
        if (m->type == FILE_CLEAR)
404
754
          ms->c.li[cont_level].got_match = 0;
405
247k
        else if (ms->c.li[cont_level].got_match) {
406
65.4k
          if (m->type == FILE_DEFAULT)
407
988
            break;
408
65.4k
        } else
409
182k
          ms->c.li[cont_level].got_match = 1;
410
411
247k
        if ((e = handle_annotation(ms, m, *firstline))
412
247k
            != 0) {
413
0
          *found_match = 1;
414
0
          *need_separator = 1;
415
0
          *printed_something = 1;
416
0
          *returnval = 1;
417
0
          return e;
418
0
        }
419
247k
        if (*m->desc) {
420
87.4k
          *found_match = 1;
421
87.4k
        }
422
247k
        if (print && *m->desc) {
423
87.4k
          *returnval = 1;
424
          /*
425
           * This continuation matched.  Print
426
           * its message, with a blank before it
427
           * if the previous item printed and
428
           * this item isn't empty.
429
           */
430
          /*
431
           * If we are going to print something,
432
           * make sure that we have a separator
433
           * first.
434
           */
435
87.4k
          if (!*printed_something) {
436
13.6k
            *printed_something = 1;
437
13.6k
            if (print_sep(ms, *firstline)
438
13.6k
                == -1)
439
0
              return -1;
440
13.6k
          }
441
          /* space if previous printed */
442
87.4k
          if (*need_separator
443
87.4k
              && (m->flag & NOSPACE) == 0) {
444
28.8k
            if (file_printf(ms, " ") == -1)
445
0
              return -1;
446
28.8k
          }
447
87.4k
          if (mprint(ms, m) == -1)
448
0
            return -1;
449
87.4k
          *need_separator = 1;
450
87.4k
        }
451
452
247k
        switch (moffset(ms, m, &bb,
453
247k
            &ms->c.li[cont_level].off)) {
454
3.45k
        case -1:
455
3.45k
        case 0:
456
3.45k
          cont_level--;
457
3.45k
          break;
458
243k
        default:
459
243k
          break;
460
247k
        }
461
462
        /*
463
         * If we see any continuations
464
         * at a higher level,
465
         * process them.
466
         */
467
247k
        if (file_check_mem(ms, ++cont_level) == -1)
468
0
          return -1;
469
247k
        break;
470
1.07M
      }
471
1.07M
    }
472
270k
    if (*printed_something) {
473
75.0k
      *firstline = 0;
474
75.0k
    }
475
270k
    if (*found_match) {
476
189k
      if ((ms->flags & MAGIC_CONTINUE) == 0)
477
0
        return *returnval;
478
      // So that we print a separator
479
189k
      *printed_something = 0;
480
189k
      *firstline = 0;
481
189k
    }
482
270k
    cont_level = 0;
483
270k
  }
484
67.8k
  return *returnval;
485
69.6k
}
486
487
file_private int
488
check_fmt(struct magic_set *ms, const char *fmt)
489
63.0k
{
490
63.0k
  file_regex_t rx;
491
63.0k
  int rc, rv = -1;
492
63.0k
        const char* pat = "%[-0-9\\.]*s";
493
494
63.0k
  if (strchr(fmt, '%') == NULL)
495
41.2k
    return 0;
496
497
21.7k
  rc = file_regcomp(ms, &rx, pat, REG_EXTENDED|REG_NOSUB);
498
21.7k
  if (rc == 0) {
499
21.7k
    rc = file_regexec(ms, &rx, fmt, 0, 0, 0);
500
21.7k
    rv = !rc;
501
21.7k
  }
502
21.7k
  file_regfree(&rx);
503
21.7k
  return rv;
504
63.0k
}
505
506
#if !defined(HAVE_STRNDUP) || defined(__aiws__) || defined(_AIX)
507
# if defined(__aiws__) || defined(_AIX)
508
#  define strndup aix_strndup /* aix is broken */
509
# endif
510
char *strndup(const char *, size_t);
511
512
char *
513
strndup(const char *str, size_t n)
514
{
515
  size_t len;
516
  char *copy;
517
518
  for (len = 0; len < n && str[len]; len++)
519
    continue;
520
  if ((copy = CAST(char *, malloc(len + 1))) == NULL)
521
    return NULL;
522
  (void)memcpy(copy, str, len);
523
  copy[len] = '\0';
524
  return copy;
525
}
526
#endif /* HAVE_STRNDUP */
527
528
static int
529
varexpand(struct magic_set *ms, char *buf, size_t len, const char *str)
530
111k
{
531
111k
  const char *ptr, *sptr, *e, *t, *ee, *et;
532
111k
  size_t l;
533
534
111k
  for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) {
535
429
    l = CAST(size_t, ptr - sptr);
536
429
    if (l >= len)
537
0
      return -1;
538
429
    memcpy(buf, sptr, l);
539
429
    buf += l;
540
429
    len -= l;
541
429
    ptr += 2;
542
429
    if (!*ptr || ptr[1] != '?')
543
0
      return -1;
544
6.43k
    for (et = t = ptr + 2; *et && *et != ':'; et++)
545
6.00k
      continue;
546
429
    if (*et != ':')
547
0
      return -1;
548
6.00k
    for (ee = e = et + 1; *ee && *ee != '}'; ee++)
549
5.57k
      continue;
550
429
    if (*ee != '}')
551
0
      return -1;
552
429
    switch (*ptr) {
553
429
    case 'x':
554
429
      if (ms->mode & 0111) {
555
0
        ptr = t;
556
0
        l = et - t;
557
429
      } else {
558
429
        ptr = e;
559
429
        l = ee - e;
560
429
      }
561
429
      break;
562
0
    default:
563
0
      return -1;
564
429
    }
565
429
    if (l >= len)
566
0
      return -1;
567
429
    memcpy(buf, ptr, l);
568
429
    buf += l;
569
429
    len -= l;
570
429
    sptr = ee + 1;
571
429
  }
572
573
111k
  l = strlen(sptr);
574
111k
  if (l >= len)
575
0
    return -1;
576
577
111k
  memcpy(buf, sptr, l);
578
111k
  buf[l] = '\0';
579
111k
  return 0;
580
111k
}
581
582
583
file_private int
584
mprint(struct magic_set *ms, struct magic *m)
585
111k
{
586
111k
  uint64_t v;
587
111k
  float vf;
588
111k
  double vd;
589
111k
  char buf[128], tbuf[26], sbuf[512], ebuf[512];
590
111k
  const char *desc;
591
111k
  union VALUETYPE *p = &ms->ms_value;
592
593
111k
  if (varexpand(ms, ebuf, sizeof(ebuf), m->desc) == -1)
594
0
    desc = m->desc;
595
111k
  else
596
111k
    desc = ebuf;
597
598
111k
#define PRINTER(value, format, stype, utype)  \
599
111k
  v = file_signextend(ms, m, CAST(uint64_t, value)); \
600
62.5k
  switch (check_fmt(ms, desc)) { \
601
0
  case -1: \
602
0
    return -1; \
603
0
  case 1: \
604
0
    if (m->flag & UNSIGNED) { \
605
0
      (void)snprintf(buf, sizeof(buf), "%" format "u", \
606
0
          CAST(utype, v)); \
607
0
    } else { \
608
0
      (void)snprintf(buf, sizeof(buf), "%" format "d", \
609
0
          CAST(stype, v)); \
610
0
    } \
611
0
    if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) \
612
0
      return -1; \
613
0
    break; \
614
62.5k
  default: \
615
62.5k
    if (m->flag & UNSIGNED) { \
616
23.5k
           if (file_printf(ms, F(ms, desc, "%" format "u"), \
617
23.5k
         CAST(utype, v)) == -1) \
618
23.5k
         return -1; \
619
38.9k
    } else { \
620
38.9k
           if (file_printf(ms, F(ms, desc, "%" format "d"), \
621
38.9k
         CAST(stype, v)) == -1) \
622
38.9k
         return -1; \
623
38.9k
    } \
624
62.5k
    break; \
625
62.5k
  } \
626
62.5k
  break
627
628
111k
    switch (m->type) {
629
17.1k
    case FILE_BYTE:
630
17.1k
    PRINTER(p->b, "", int8_t, uint8_t);
631
632
17.1k
    case FILE_SHORT:
633
6.19k
    case FILE_BESHORT:
634
15.0k
    case FILE_LESHORT:
635
15.0k
    PRINTER(p->h, "", int16_t, uint16_t);
636
637
15.0k
    case FILE_LONG:
638
21.2k
    case FILE_BELONG:
639
28.4k
    case FILE_LELONG:
640
28.4k
    case FILE_MELONG:
641
28.4k
    PRINTER(p->l, "", int32_t, uint32_t);
642
643
28.4k
    case FILE_QUAD:
644
1.34k
    case FILE_BEQUAD:
645
1.82k
    case FILE_LEQUAD:
646
1.89k
  case FILE_OFFSET:
647
1.89k
    PRINTER(p->q, INT64_T_FORMAT, long long, unsigned long long);
648
649
39.0k
    case FILE_STRING:
650
39.7k
    case FILE_PSTRING:
651
39.8k
    case FILE_BESTRING16:
652
41.0k
    case FILE_LESTRING16:
653
41.0k
    if (m->reln == '=' || m->reln == '!') {
654
20.3k
      if (file_printf(ms, F(ms, desc, "%s"),
655
20.3k
          file_printable(ms, sbuf, sizeof(sbuf), m->value.s,
656
20.3k
          sizeof(m->value.s))) == -1)
657
0
        return -1;
658
20.3k
    }
659
20.6k
    else {
660
20.6k
      char *str = p->s;
661
662
      /* compute t before we mangle the string? */
663
664
20.6k
      if (*m->value.s == '\0')
665
19.2k
        str[strcspn(str, "\r\n")] = '\0';
666
667
20.6k
      if (m->str_flags & STRING_TRIM)
668
345
        str = file_strtrim(str);
669
670
20.6k
      if (file_printf(ms, F(ms, desc, "%s"),
671
20.6k
          file_printable(ms, sbuf, sizeof(sbuf), str,
672
20.6k
        sizeof(p->s) - (str - p->s))) == -1)
673
0
        return -1;
674
675
20.6k
      if (m->type == FILE_PSTRING) {
676
716
        size_t l = file_pstring_length_size(ms, m);
677
716
        if (l == FILE_BADSIZE)
678
0
          return -1;
679
716
      }
680
20.6k
    }
681
41.0k
    break;
682
683
41.0k
  case FILE_DATE:
684
103
  case FILE_BEDATE:
685
180
  case FILE_LEDATE:
686
214
  case FILE_MEDATE:
687
214
    if (file_printf(ms, F(ms, desc, "%s"),
688
214
        file_fmtdatetime(tbuf, sizeof(tbuf), p->l, 0)) == -1)
689
0
      return -1;
690
214
    break;
691
692
214
  case FILE_LDATE:
693
213
  case FILE_BELDATE:
694
213
  case FILE_LELDATE:
695
213
  case FILE_MELDATE:
696
213
    if (file_printf(ms, F(ms, desc, "%s"),
697
213
        file_fmtdatetime(tbuf, sizeof(tbuf), p->l, FILE_T_LOCAL))
698
213
      == -1)
699
0
      return -1;
700
213
    break;
701
702
213
  case FILE_QDATE:
703
216
  case FILE_BEQDATE:
704
216
  case FILE_LEQDATE:
705
216
    if (file_printf(ms, F(ms, desc, "%s"),
706
216
        file_fmtdatetime(tbuf, sizeof(tbuf), p->q, 0)) == -1)
707
0
      return -1;
708
216
    break;
709
710
216
  case FILE_QLDATE:
711
0
  case FILE_BEQLDATE:
712
12
  case FILE_LEQLDATE:
713
12
    if (file_printf(ms, F(ms, desc, "%s"),
714
12
        file_fmtdatetime(tbuf, sizeof(tbuf), p->q, FILE_T_LOCAL)) == -1)
715
0
      return -1;
716
12
    break;
717
718
268
  case FILE_QWDATE:
719
268
  case FILE_BEQWDATE:
720
940
  case FILE_LEQWDATE:
721
940
    if (file_printf(ms, F(ms, desc, "%s"),
722
940
        file_fmtdatetime(tbuf, sizeof(tbuf), p->q, FILE_T_WINDOWS))
723
940
        == -1)
724
0
      return -1;
725
940
    break;
726
727
940
  case FILE_FLOAT:
728
0
  case FILE_BEFLOAT:
729
444
  case FILE_LEFLOAT:
730
444
    vf = p->f;
731
444
    switch (check_fmt(ms, desc)) {
732
0
    case -1:
733
0
      return -1;
734
0
    case 1:
735
0
      (void)snprintf(buf, sizeof(buf), "%g", vf);
736
0
      if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
737
0
        return -1;
738
0
      break;
739
444
    default:
740
444
      if (file_printf(ms, F(ms, desc, "%g"), vf) == -1)
741
0
        return -1;
742
444
      break;
743
444
    }
744
444
      break;
745
746
444
  case FILE_DOUBLE:
747
0
  case FILE_BEDOUBLE:
748
64
  case FILE_LEDOUBLE:
749
64
    vd = p->d;
750
64
    switch (check_fmt(ms, desc)) {
751
0
    case -1:
752
0
      return -1;
753
0
    case 1:
754
0
      (void)snprintf(buf, sizeof(buf), "%g", vd);
755
0
      if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
756
0
        return -1;
757
0
      break;
758
64
    default:
759
64
      if (file_printf(ms, F(ms, desc, "%g"), vd) == -1)
760
0
        return -1;
761
64
      break;
762
64
    }
763
64
      break;
764
765
364
  case FILE_SEARCH:
766
499
  case FILE_REGEX: {
767
499
    char *cp, *scp;
768
499
    int rval;
769
770
499
    cp = strndup(RCAST(const char *, ms->search.s),
771
499
        ms->search.rm_len);
772
499
    if (cp == NULL) {
773
0
      file_oomem(ms, ms->search.rm_len);
774
0
      return -1;
775
0
    }
776
499
    scp = (m->str_flags & STRING_TRIM) ? file_strtrim(cp) : cp;
777
778
499
    rval = file_printf(ms, F(ms, desc, "%s"), file_printable(ms,
779
499
        sbuf, sizeof(sbuf), scp, ms->search.rm_len));
780
499
    free(cp);
781
782
499
    if (rval == -1)
783
0
      return -1;
784
499
    break;
785
499
  }
786
787
758
  case FILE_DEFAULT:
788
761
  case FILE_CLEAR:
789
761
      if (file_printf(ms, "%s", m->desc) == -1)
790
0
      return -1;
791
761
    break;
792
793
773
  case FILE_INDIRECT:
794
773
  case FILE_USE:
795
3.84k
  case FILE_NAME:
796
3.84k
    break;
797
176
  case FILE_DER:
798
176
    if (file_printf(ms, F(ms, desc, "%s"),
799
176
        file_printable(ms, sbuf, sizeof(sbuf), ms->ms_value.s,
800
176
      sizeof(ms->ms_value.s))) == -1)
801
0
      return -1;
802
176
    break;
803
410
  case FILE_GUID:
804
410
    (void) file_print_guid(buf, sizeof(buf), ms->ms_value.guid);
805
410
    if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
806
0
      return -1;
807
410
    break;
808
410
  case FILE_MSDOSDATE:
809
0
  case FILE_BEMSDOSDATE:
810
20
  case FILE_LEMSDOSDATE:
811
20
    if (file_printf(ms, F(ms, desc, "%s"),
812
20
        file_fmtdate(tbuf, sizeof(tbuf), p->h)) == -1)
813
0
      return -1;
814
20
    break;
815
20
  case FILE_MSDOSTIME:
816
0
  case FILE_BEMSDOSTIME:
817
20
  case FILE_LEMSDOSTIME:
818
20
    if (file_printf(ms, F(ms, desc, "%s"),
819
20
        file_fmttime(tbuf, sizeof(tbuf), p->h)) == -1)
820
0
      return -1;
821
20
    break;
822
20
  case FILE_OCTAL:
823
0
    file_fmtnum(buf, sizeof(buf), m->value.s, 8);
824
0
    if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
825
0
      return -1;
826
0
    break;
827
0
  default:
828
0
    file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
829
0
    return -1;
830
111k
  }
831
111k
  return 0;
832
111k
}
833
834
file_private int
835
moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
836
    int32_t *op)
837
539k
{
838
539k
  size_t nbytes = b->flen;
839
539k
  int32_t o;
840
841
539k
    switch (m->type) {
842
159k
    case FILE_BYTE:
843
159k
    o = CAST(int32_t, (ms->offset + sizeof(char)));
844
159k
    break;
845
846
12.6k
    case FILE_SHORT:
847
44.1k
    case FILE_BESHORT:
848
71.2k
    case FILE_LESHORT:
849
71.2k
  case FILE_MSDOSDATE:
850
71.2k
  case FILE_LEMSDOSDATE:
851
71.2k
  case FILE_BEMSDOSDATE:
852
71.2k
  case FILE_MSDOSTIME:
853
71.2k
  case FILE_LEMSDOSTIME:
854
71.2k
  case FILE_BEMSDOSTIME:
855
71.2k
    o = CAST(int32_t, (ms->offset + sizeof(short)));
856
71.2k
    break;
857
858
3.20k
    case FILE_LONG:
859
66.0k
    case FILE_BELONG:
860
90.1k
    case FILE_LELONG:
861
90.2k
    case FILE_MELONG:
862
90.2k
    o = CAST(int32_t, (ms->offset + sizeof(int32_t)));
863
90.2k
    break;
864
865
20.6k
    case FILE_QUAD:
866
25.2k
    case FILE_BEQUAD:
867
26.0k
    case FILE_LEQUAD:
868
26.0k
    o = CAST(int32_t, (ms->offset + sizeof(int64_t)));
869
26.0k
    break;
870
871
70.9k
    case FILE_STRING:
872
71.6k
    case FILE_PSTRING:
873
71.7k
    case FILE_BESTRING16:
874
72.9k
    case FILE_LESTRING16:
875
72.9k
  case FILE_OCTAL:
876
72.9k
    if (m->reln == '=' || m->reln == '!') {
877
26.9k
      o = ms->offset + m->vallen;
878
46.0k
    } else {
879
46.0k
      union VALUETYPE *p = &ms->ms_value;
880
881
46.0k
      if (*m->value.s == '\0')
882
40.3k
        p->s[strcspn(p->s, "\r\n")] = '\0';
883
46.0k
      o = CAST(uint32_t, (ms->offset + strlen(p->s)));
884
46.0k
      if (m->type == FILE_PSTRING) {
885
720
        size_t l = file_pstring_length_size(ms, m);
886
720
        if (l == FILE_BADSIZE)
887
0
          return -1;
888
720
        o += CAST(uint32_t, l);
889
720
      }
890
46.0k
    }
891
72.9k
    break;
892
893
72.9k
  case FILE_DATE:
894
103
  case FILE_BEDATE:
895
180
  case FILE_LEDATE:
896
214
  case FILE_MEDATE:
897
214
    o = CAST(int32_t, (ms->offset + sizeof(uint32_t)));
898
214
    break;
899
900
0
  case FILE_LDATE:
901
213
  case FILE_BELDATE:
902
213
  case FILE_LELDATE:
903
213
  case FILE_MELDATE:
904
213
    o = CAST(int32_t, (ms->offset + sizeof(uint32_t)));
905
213
    break;
906
907
0
  case FILE_QDATE:
908
216
  case FILE_BEQDATE:
909
216
  case FILE_LEQDATE:
910
216
    o = CAST(int32_t, (ms->offset + sizeof(uint64_t)));
911
216
    break;
912
913
0
  case FILE_QLDATE:
914
0
  case FILE_BEQLDATE:
915
12
  case FILE_LEQLDATE:
916
12
    o = CAST(int32_t, (ms->offset + sizeof(uint64_t)));
917
12
    break;
918
919
0
    case FILE_FLOAT:
920
0
    case FILE_BEFLOAT:
921
444
    case FILE_LEFLOAT:
922
444
    o = CAST(int32_t, (ms->offset + sizeof(float)));
923
444
    break;
924
925
0
    case FILE_DOUBLE:
926
0
    case FILE_BEDOUBLE:
927
64
    case FILE_LEDOUBLE:
928
64
    o = CAST(int32_t, (ms->offset + sizeof(double)));
929
64
    break;
930
931
643
  case FILE_REGEX:
932
643
    if ((m->str_flags & REGEX_OFFSET_START) != 0)
933
23
      o = CAST(int32_t, ms->search.offset);
934
620
    else
935
620
      o = CAST(int32_t,
936
643
          (ms->search.offset + ms->search.rm_len));
937
643
    break;
938
939
4.75k
  case FILE_SEARCH:
940
4.75k
    if ((m->str_flags & REGEX_OFFSET_START) != 0)
941
84
      o = CAST(int32_t, ms->search.offset);
942
4.67k
    else
943
4.67k
      o = CAST(int32_t, (ms->search.offset + m->vallen));
944
4.75k
    break;
945
946
754
  case FILE_CLEAR:
947
6.29k
  case FILE_DEFAULT:
948
16.4k
  case FILE_INDIRECT:
949
16.5k
  case FILE_OFFSET:
950
43.2k
  case FILE_USE:
951
43.2k
    o = ms->offset;
952
43.2k
    break;
953
954
23.1k
  case FILE_DER:
955
23.1k
    o = der_offs(ms, m, nbytes);
956
23.1k
    if (o == -1 || CAST(size_t, o) > nbytes) {
957
0
      if ((ms->flags & MAGIC_DEBUG) != 0) {
958
0
        (void)fprintf(stderr,
959
0
            "Bad DER offset %d nbytes=%"
960
0
            SIZE_T_FORMAT "u", o, nbytes);
961
0
      }
962
0
      *op = 0;
963
0
      return 0;
964
0
    }
965
23.1k
    break;
966
967
23.1k
  case FILE_GUID:
968
410
    o = CAST(int32_t, (ms->offset + 2 * sizeof(uint64_t)));
969
410
    break;
970
971
45.5k
  default:
972
45.5k
    o = 0;
973
45.5k
    break;
974
539k
  }
975
976
539k
  if (CAST(size_t, o) > nbytes) {
977
#if 0
978
    file_error(ms, 0, "Offset out of range %" SIZE_T_FORMAT
979
        "u > %" SIZE_T_FORMAT "u", (size_t)o, nbytes);
980
#endif
981
23.1k
    return -1;
982
23.1k
  }
983
516k
  *op = o;
984
516k
  return 1;
985
539k
}
986
987
file_private uint32_t
988
cvt_id3(struct magic_set *ms, uint32_t v)
989
877
{
990
877
  v = ((((v >>  0) & 0x7f) <<  0) |
991
877
       (((v >>  8) & 0x7f) <<  7) |
992
877
       (((v >> 16) & 0x7f) << 14) |
993
877
       (((v >> 24) & 0x7f) << 21));
994
877
  if ((ms->flags & MAGIC_DEBUG) != 0)
995
0
    fprintf(stderr, "id3 offs=%u\n", v);
996
877
  return v;
997
877
}
998
999
file_private int
1000
cvt_flip(int type, int flip)
1001
64.8M
{
1002
64.8M
  if (flip == 0)
1003
64.7M
    return type;
1004
10.5k
  switch (type) {
1005
57
  case FILE_BESHORT:
1006
57
    return FILE_LESHORT;
1007
1.17k
  case FILE_BELONG:
1008
1.17k
    return FILE_LELONG;
1009
3
  case FILE_BEDATE:
1010
3
    return FILE_LEDATE;
1011
0
  case FILE_BELDATE:
1012
0
    return FILE_LELDATE;
1013
3
  case FILE_BEQUAD:
1014
3
    return FILE_LEQUAD;
1015
18
  case FILE_BEQDATE:
1016
18
    return FILE_LEQDATE;
1017
0
  case FILE_BEQLDATE:
1018
0
    return FILE_LEQLDATE;
1019
0
  case FILE_BEQWDATE:
1020
0
    return FILE_LEQWDATE;
1021
8.52k
  case FILE_LESHORT:
1022
8.52k
    return FILE_BESHORT;
1023
335
  case FILE_LELONG:
1024
335
    return FILE_BELONG;
1025
4
  case FILE_LEDATE:
1026
4
    return FILE_BEDATE;
1027
0
  case FILE_LELDATE:
1028
0
    return FILE_BELDATE;
1029
28
  case FILE_LEQUAD:
1030
28
    return FILE_BEQUAD;
1031
0
  case FILE_LEQDATE:
1032
0
    return FILE_BEQDATE;
1033
7
  case FILE_LEQLDATE:
1034
7
    return FILE_BEQLDATE;
1035
0
  case FILE_LEQWDATE:
1036
0
    return FILE_BEQWDATE;
1037
0
  case FILE_BEFLOAT:
1038
0
    return FILE_LEFLOAT;
1039
0
  case FILE_LEFLOAT:
1040
0
    return FILE_BEFLOAT;
1041
0
  case FILE_BEDOUBLE:
1042
0
    return FILE_LEDOUBLE;
1043
0
  case FILE_LEDOUBLE:
1044
0
    return FILE_BEDOUBLE;
1045
414
  default:
1046
414
    return type;
1047
10.5k
  }
1048
10.5k
}
1049
#define DO_CVT(fld, type) \
1050
22.7M
  if (m->num_mask) \
1051
22.7M
    switch (m->mask_op & FILE_OPS_MASK) { \
1052
3.23M
    case FILE_OPAND: \
1053
3.23M
      p->fld &= CAST(type, m->num_mask); \
1054
3.23M
      break; \
1055
0
    case FILE_OPOR: \
1056
0
      p->fld |= CAST(type, m->num_mask); \
1057
0
      break; \
1058
44
    case FILE_OPXOR: \
1059
44
      p->fld ^= CAST(type, m->num_mask); \
1060
44
      break; \
1061
223
    case FILE_OPADD: \
1062
223
      p->fld += CAST(type, m->num_mask); \
1063
223
      break; \
1064
14.4k
    case FILE_OPMINUS: \
1065
14.4k
      p->fld -= CAST(type, m->num_mask); \
1066
14.4k
      break; \
1067
55
    case FILE_OPMULTIPLY: \
1068
55
      p->fld *= CAST(type, m->num_mask); \
1069
55
      break; \
1070
942
    case FILE_OPDIVIDE: \
1071
942
      if (CAST(type, m->num_mask) == 0) \
1072
942
        return -1; \
1073
942
      p->fld /= CAST(type, m->num_mask); \
1074
942
      break; \
1075
21.1k
    case FILE_OPMODULO: \
1076
21.1k
      if (CAST(type, m->num_mask) == 0) \
1077
21.1k
        return -1; \
1078
21.1k
      p->fld %= CAST(type, m->num_mask); \
1079
21.1k
      break; \
1080
3.26M
    } \
1081
22.7M
  if (m->mask_op & FILE_OPINVERSE) \
1082
22.7M
    p->fld = ~p->fld \
1083
1084
file_private int
1085
cvt_8(union VALUETYPE *p, const struct magic *m)
1086
1.06M
{
1087
1.06M
  DO_CVT(b, uint8_t);
1088
1.06M
  return 0;
1089
1.06M
}
1090
1091
file_private int
1092
cvt_16(union VALUETYPE *p, const struct magic *m)
1093
6.07M
{
1094
6.07M
  DO_CVT(h, uint16_t);
1095
6.07M
  return 0;
1096
6.07M
}
1097
1098
file_private int
1099
cvt_32(union VALUETYPE *p, const struct magic *m)
1100
14.3M
{
1101
14.3M
  DO_CVT(l, uint32_t);
1102
14.3M
  return 0;
1103
14.3M
}
1104
1105
file_private int
1106
cvt_64(union VALUETYPE *p, const struct magic *m)
1107
1.26M
{
1108
1.26M
  DO_CVT(q, uint64_t);
1109
1.26M
  return 0;
1110
1.26M
}
1111
1112
#define DO_CVT2(fld, type) \
1113
1.43k
  if (m->num_mask) \
1114
1.43k
    switch (m->mask_op & FILE_OPS_MASK) { \
1115
0
    case FILE_OPADD: \
1116
0
      p->fld += CAST(type, m->num_mask); \
1117
0
      break; \
1118
0
    case FILE_OPMINUS: \
1119
0
      p->fld -= CAST(type, m->num_mask); \
1120
0
      break; \
1121
0
    case FILE_OPMULTIPLY: \
1122
0
      p->fld *= CAST(type, m->num_mask); \
1123
0
      break; \
1124
0
    case FILE_OPDIVIDE: \
1125
0
      if (CAST(type, m->num_mask) == 0) \
1126
0
        return -1; \
1127
0
      p->fld /= CAST(type, m->num_mask); \
1128
0
      break; \
1129
0
    } \
1130
1131
file_private int
1132
cvt_float(union VALUETYPE *p, const struct magic *m)
1133
1.18k
{
1134
1.18k
  DO_CVT2(f, float);
1135
1.18k
  return 0;
1136
1.18k
}
1137
1138
file_private int
1139
cvt_double(union VALUETYPE *p, const struct magic *m)
1140
245
{
1141
245
  DO_CVT2(d, double);
1142
245
  return 0;
1143
245
}
1144
1145
/*
1146
 * Convert the byte order of the data we are looking at
1147
 * While we're here, let's apply the mask operation
1148
 * (unless you have a better idea)
1149
 */
1150
file_private int
1151
mconvert(struct magic_set *ms, struct magic *m, int flip)
1152
64.7M
{
1153
64.7M
  union VALUETYPE *p = &ms->ms_value;
1154
1155
64.7M
  switch (cvt_flip(m->type, flip)) {
1156
1.06M
  case FILE_BYTE:
1157
1.06M
    if (cvt_8(p, m) == -1)
1158
0
      goto out;
1159
1.06M
    return 1;
1160
734k
  case FILE_SHORT:
1161
734k
  case FILE_MSDOSDATE:
1162
734k
  case FILE_LEMSDOSDATE:
1163
734k
  case FILE_BEMSDOSDATE:
1164
734k
  case FILE_MSDOSTIME:
1165
734k
  case FILE_LEMSDOSTIME:
1166
734k
  case FILE_BEMSDOSTIME:
1167
734k
    if (cvt_16(p, m) == -1)
1168
0
      goto out;
1169
734k
    return 1;
1170
1.08M
  case FILE_LONG:
1171
1.08M
  case FILE_DATE:
1172
1.08M
  case FILE_LDATE:
1173
1.08M
    if (cvt_32(p, m) == -1)
1174
0
      goto out;
1175
1.08M
    return 1;
1176
47.6k
  case FILE_QUAD:
1177
47.6k
  case FILE_QDATE:
1178
47.6k
  case FILE_QLDATE:
1179
47.9k
  case FILE_QWDATE:
1180
49.9k
  case FILE_OFFSET:
1181
49.9k
    if (cvt_64(p, m) == -1)
1182
0
      goto out;
1183
49.9k
    return 1;
1184
40.8M
  case FILE_STRING:
1185
40.8M
  case FILE_BESTRING16:
1186
40.9M
  case FILE_LESTRING16:
1187
40.9M
  case FILE_OCTAL: {
1188
    /* Null terminate and eat *trailing* return */
1189
40.9M
    p->s[sizeof(p->s) - 1] = '\0';
1190
40.9M
    return 1;
1191
40.9M
  }
1192
18.0k
  case FILE_PSTRING: {
1193
18.0k
    char *ptr1, *ptr2;
1194
18.0k
    size_t len, sz = file_pstring_length_size(ms, m);
1195
18.0k
    if (sz == FILE_BADSIZE)
1196
0
      return 0;
1197
18.0k
    ptr1 = p->s;
1198
18.0k
    ptr2 = ptr1 + sz;
1199
18.0k
    len = file_pstring_get_length(ms, m, ptr1);
1200
18.0k
    if (len == FILE_BADSIZE)
1201
18
      return 0;
1202
18.0k
    sz = sizeof(p->s) - sz; /* maximum length of string */
1203
18.0k
    if (len >= sz) {
1204
      /*
1205
       * The size of the pascal string length (sz)
1206
       * is 1, 2, or 4. We need at least 1 byte for NUL
1207
       * termination, but we've already truncated the
1208
       * string by p->s, so we need to deduct sz.
1209
       * Because we can use one of the bytes of the length
1210
       * after we shifted as NUL termination.
1211
       */
1212
12.3k
      len = sz;
1213
12.3k
    }
1214
1.82M
    while (len--)
1215
1.80M
      *ptr1++ = *ptr2++;
1216
18.0k
    *ptr1 = '\0';
1217
18.0k
    return 1;
1218
18.0k
  }
1219
3.10M
  case FILE_BESHORT:
1220
3.10M
    p->h = CAST(short, BE16(p));
1221
3.10M
    if (cvt_16(p, m) == -1)
1222
0
      goto out;
1223
3.10M
    return 1;
1224
9.07M
  case FILE_BELONG:
1225
9.07M
  case FILE_BEDATE:
1226
9.07M
  case FILE_BELDATE:
1227
9.07M
    p->l = CAST(int32_t, BE32(p));
1228
9.07M
    if (cvt_32(p, m) == -1)
1229
0
      goto out;
1230
9.07M
    return 1;
1231
633k
  case FILE_BEQUAD:
1232
634k
  case FILE_BEQDATE:
1233
634k
  case FILE_BEQLDATE:
1234
634k
  case FILE_BEQWDATE:
1235
634k
    p->q = CAST(uint64_t, BE64(p));
1236
634k
    if (cvt_64(p, m) == -1)
1237
0
      goto out;
1238
634k
    return 1;
1239
2.23M
  case FILE_LESHORT:
1240
2.23M
    p->h = CAST(short, LE16(p));
1241
2.23M
    if (cvt_16(p, m) == -1)
1242
0
      goto out;
1243
2.23M
    return 1;
1244
4.18M
  case FILE_LELONG:
1245
4.18M
  case FILE_LEDATE:
1246
4.18M
  case FILE_LELDATE:
1247
4.18M
    p->l = CAST(int32_t, LE32(p));
1248
4.18M
    if (cvt_32(p, m) == -1)
1249
0
      goto out;
1250
4.18M
    return 1;
1251
578k
  case FILE_LEQUAD:
1252
578k
  case FILE_LEQDATE:
1253
578k
  case FILE_LEQLDATE:
1254
579k
  case FILE_LEQWDATE:
1255
579k
    p->q = CAST(uint64_t, LE64(p));
1256
579k
    if (cvt_64(p, m) == -1)
1257
0
      goto out;
1258
579k
    return 1;
1259
28
  case FILE_MELONG:
1260
62
  case FILE_MEDATE:
1261
62
  case FILE_MELDATE:
1262
62
    p->l = CAST(int32_t, ME32(p));
1263
62
    if (cvt_32(p, m) == -1)
1264
0
      goto out;
1265
62
    return 1;
1266
0
  case FILE_FLOAT:
1267
0
    if (cvt_float(p, m) == -1)
1268
0
      goto out;
1269
0
    return 1;
1270
0
  case FILE_BEFLOAT:
1271
0
    p->l = BE32(p);
1272
0
    if (cvt_float(p, m) == -1)
1273
0
      goto out;
1274
0
    return 1;
1275
1.18k
  case FILE_LEFLOAT:
1276
1.18k
    p->l = LE32(p);
1277
1.18k
    if (cvt_float(p, m) == -1)
1278
0
      goto out;
1279
1.18k
    return 1;
1280
0
  case FILE_DOUBLE:
1281
0
    if (cvt_double(p, m) == -1)
1282
0
      goto out;
1283
0
    return 1;
1284
106
  case FILE_BEDOUBLE:
1285
106
    p->q = BE64(p);
1286
106
    if (cvt_double(p, m) == -1)
1287
0
      goto out;
1288
106
    return 1;
1289
139
  case FILE_LEDOUBLE:
1290
139
    p->q = LE64(p);
1291
139
    if (cvt_double(p, m) == -1)
1292
0
      goto out;
1293
139
    return 1;
1294
160k
  case FILE_REGEX:
1295
560k
  case FILE_SEARCH:
1296
566k
  case FILE_DEFAULT:
1297
567k
  case FILE_CLEAR:
1298
567k
  case FILE_NAME:
1299
567k
  case FILE_USE:
1300
873k
  case FILE_DER:
1301
1.01M
  case FILE_GUID:
1302
1.01M
    return 1;
1303
0
  default:
1304
0
    file_magerror(ms, "invalid type %d in mconvert()", m->type);
1305
0
    return 0;
1306
64.7M
  }
1307
0
out:
1308
0
  file_magerror(ms, "zerodivide in mconvert()");
1309
0
  return 0;
1310
64.7M
}
1311
1312
1313
file_private void
1314
mdebug(uint32_t offset, const char *str, size_t len)
1315
0
{
1316
0
  (void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset);
1317
0
  file_showstr(stderr, str, len);
1318
0
  (void) fputc('\n', stderr);
1319
0
  (void) fputc('\n', stderr);
1320
0
}
1321
1322
file_private int
1323
mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
1324
    const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
1325
75.9M
{
1326
75.9M
  size_t size = sizeof(*p);
1327
  /*
1328
   * Note: FILE_SEARCH and FILE_REGEX do not actually copy
1329
   * anything, but setup pointers into the source
1330
   */
1331
75.9M
  if (indir == 0) {
1332
75.8M
    switch (type) {
1333
306k
    case FILE_DER:
1334
960k
    case FILE_SEARCH:
1335
960k
      if (offset > nbytes)
1336
48.4k
        offset = CAST(uint32_t, nbytes);
1337
960k
      ms->search.s = RCAST(const char *, s) + offset;
1338
960k
      ms->search.s_len = nbytes - offset;
1339
960k
      ms->search.offset = offset;
1340
960k
      return 0;
1341
1342
161k
    case FILE_REGEX: {
1343
161k
      const char *b;
1344
161k
      const char *c;
1345
161k
      const char *last; /* end of search region */
1346
161k
      const char *buf;  /* start of search region */
1347
161k
      const char *end;
1348
161k
      size_t lines, linecnt, bytecnt;
1349
1350
161k
      if (s == NULL || nbytes < offset) {
1351
848
        ms->search.s_len = 0;
1352
848
        ms->search.s = NULL;
1353
848
        return 0;
1354
848
      }
1355
1356
160k
      if (m->str_flags & REGEX_LINE_COUNT) {
1357
40.0k
        linecnt = m->str_range;
1358
40.0k
        bytecnt = linecnt * 80;
1359
120k
      } else {
1360
120k
        linecnt = 0;
1361
120k
        bytecnt = m->str_range;
1362
120k
      }
1363
1364
160k
      if (bytecnt == 0 || bytecnt > nbytes - offset)
1365
154k
        bytecnt = nbytes - offset;
1366
160k
      if (bytecnt > ms->regex_max)
1367
9.77k
        bytecnt = ms->regex_max;
1368
1369
160k
      buf = RCAST(const char *, s) + offset;
1370
160k
      end = last = RCAST(const char *, s) + bytecnt + offset;
1371
      /* mget() guarantees buf <= last */
1372
330k
      for (lines = linecnt, b = buf; lines && b < end &&
1373
330k
           ((b = CAST(const char *,
1374
206k
         memchr(c = b, '\n', CAST(size_t, (end - b)))))
1375
206k
           || (b = CAST(const char *,
1376
81.8k
         memchr(c, '\r', CAST(size_t, (end - c))))));
1377
170k
           lines--, b++) {
1378
170k
        if (b < end - 1 && b[0] == '\r' && b[1] == '\n')
1379
0
          b++;
1380
170k
        if (b < end - 1 && b[0] == '\n')
1381
123k
          b++;
1382
170k
        last = b;
1383
170k
      }
1384
160k
      if (lines)
1385
38.5k
        last = end;
1386
1387
160k
      ms->search.s = buf;
1388
160k
      ms->search.s_len = last - buf;
1389
160k
      ms->search.offset = offset;
1390
160k
      ms->search.rm_len = 0;
1391
160k
      return 0;
1392
161k
    }
1393
126
    case FILE_BESTRING16:
1394
47.8k
    case FILE_LESTRING16: {
1395
47.8k
      const unsigned char *src = s + offset;
1396
47.8k
      const unsigned char *esrc = s + nbytes;
1397
47.8k
      char *dst = p->s;
1398
47.8k
      char *edst = &p->s[sizeof(p->s) - 1];
1399
1400
47.8k
      if (type == FILE_BESTRING16)
1401
126
        src++;
1402
1403
      /* check that offset is within range */
1404
47.8k
      if (offset >= nbytes)
1405
1.30k
        break;
1406
2.37M
      for (/*EMPTY*/; src < esrc; src += 2, dst++) {
1407
2.34M
        if (dst < edst)
1408
2.33M
          *dst = *src;
1409
11.0k
        else
1410
11.0k
          break;
1411
2.33M
        if (*dst == '\0') {
1412
880k
          if (type == FILE_BESTRING16 ?
1413
3.86k
              *(src - 1) != '\0' :
1414
880k
              ((src + 1 < esrc) &&
1415
876k
              *(src + 1) != '\0'))
1416
260k
            *dst = ' ';
1417
880k
        }
1418
2.33M
      }
1419
46.5k
      *edst = '\0';
1420
46.5k
      return 0;
1421
47.8k
    }
1422
49.5M
    case FILE_STRING: /* XXX - these two should not need */
1423
49.5M
    case FILE_PSTRING: /* to copy anything, but do anyway. */
1424
49.5M
      if (m->str_range != 0 && m->str_range < sizeof(*p))
1425
15
        size = m->str_range;
1426
49.5M
      break;
1427
25.0M
    default:
1428
25.0M
      break;
1429
75.8M
    }
1430
75.8M
  }
1431
1432
74.7M
  if (type == FILE_OFFSET) {
1433
2.01k
    (void)memset(p, '\0', sizeof(*p));
1434
2.01k
    p->q = offset;
1435
2.01k
    return 0;
1436
2.01k
  }
1437
1438
74.7M
  if (offset >= nbytes) {
1439
5.00M
    (void)memset(p, '\0', sizeof(*p));
1440
5.00M
    return 0;
1441
5.00M
  }
1442
69.7M
  if (nbytes - offset < size)
1443
47.5M
    nbytes = nbytes - offset;
1444
22.1M
  else
1445
22.1M
    nbytes = size;
1446
1447
69.7M
  (void)memcpy(p, s + offset, nbytes);
1448
1449
  /*
1450
   * the usefulness of padding with zeroes eludes me, it
1451
   * might even cause problems
1452
   */
1453
69.7M
  if (nbytes < sizeof(*p))
1454
47.5M
    (void)memset(RCAST(char *, RCAST(void *, p)) + nbytes, '\0',
1455
47.5M
        sizeof(*p) - nbytes);
1456
69.7M
  return 0;
1457
74.7M
}
1458
1459
file_private int
1460
do_ops(struct magic_set *ms, struct magic *m, uint32_t *rv, intmax_t lhs,
1461
    intmax_t off)
1462
88.4k
{
1463
88.4k
  intmax_t offset;
1464
  // On purpose not INTMAX_MAX
1465
88.4k
  if (lhs >= UINT_MAX || lhs <= INT_MIN ||
1466
88.4k
      off >= UINT_MAX || off <= INT_MIN) {
1467
849
    if ((ms->flags & MAGIC_DEBUG) != 0)
1468
0
      fprintf(stderr, "lhs/off overflow %jd %jd\n", lhs, off);
1469
849
    return 1;
1470
849
  }
1471
     
1472
87.5k
  if (off) {
1473
60.4k
    switch (m->in_op & FILE_OPS_MASK) {
1474
11
    case FILE_OPAND:
1475
11
      offset = lhs & off;
1476
11
      break;
1477
0
    case FILE_OPOR:
1478
0
      offset = lhs | off;
1479
0
      break;
1480
0
    case FILE_OPXOR:
1481
0
      offset = lhs ^ off;
1482
0
      break;
1483
56.4k
    case FILE_OPADD:
1484
56.4k
      offset = lhs + off;
1485
56.4k
      break;
1486
652
    case FILE_OPMINUS:
1487
652
      offset = lhs - off;
1488
652
      break;
1489
3.25k
    case FILE_OPMULTIPLY:
1490
3.25k
      offset = lhs * off;
1491
3.25k
      break;
1492
17
    case FILE_OPDIVIDE:
1493
17
      offset = lhs / off;
1494
17
      break;
1495
0
    case FILE_OPMODULO:
1496
0
      offset = lhs % off;
1497
0
      break;
1498
60.4k
    }
1499
60.4k
  } else
1500
27.1k
    offset = lhs;
1501
87.5k
  if (m->in_op & FILE_OPINVERSE)
1502
0
    offset = ~offset;
1503
87.5k
  if (offset >= UINT_MAX) {
1504
201
    if ((ms->flags & MAGIC_DEBUG) != 0)
1505
0
      fprintf(stderr, "offset overflow %jd\n", offset);
1506
201
    return 1;
1507
201
  }
1508
87.3k
  *rv = CAST(uint32_t, offset);
1509
87.3k
  return 0;
1510
87.5k
}
1511
1512
file_private int
1513
msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
1514
    const struct buffer *b, size_t o, unsigned int cont_level)
1515
75.8M
{
1516
75.8M
  int32_t offset;
1517
75.8M
  if (m->flag & OFFNEGATIVE) {
1518
192k
    offset = -m->offset;
1519
192k
    if (cont_level > 0) {
1520
7.36k
      if (m->flag & (OFFADD|INDIROFFADD))
1521
5.09k
        goto normal;
1522
#if 0
1523
      file_error(ms, 0, "negative offset %d at continuation"
1524
          "level %u", m->offset, cont_level);
1525
      return -1;
1526
#endif
1527
7.36k
    }
1528
187k
    if (buffer_fill(b) == -1)
1529
13.9k
      return -1;
1530
173k
    if (o != 0) {
1531
      // Not yet!
1532
0
      file_magerror(ms, "non zero offset %" SIZE_T_FORMAT
1533
0
          "u at level %u", o, cont_level);
1534
0
      return -1;
1535
0
    }
1536
173k
    if (CAST(size_t, m->offset) > b->elen)
1537
35.7k
      return -1;
1538
138k
    buffer_init(bb, -1, NULL, b->ebuf, b->elen);
1539
138k
    ms->eoffset = ms->offset = CAST(int32_t, b->elen - m->offset);
1540
75.6M
  } else {
1541
75.6M
    offset = m->offset;
1542
75.6M
    if (cont_level == 0) {
1543
74.5M
normal:
1544
      // XXX: Pass real fd, then who frees bb?
1545
74.5M
      buffer_init(bb, -1, NULL, b->fbuf, b->flen);
1546
74.5M
      ms->offset = offset;
1547
74.5M
      ms->eoffset = 0;
1548
74.5M
    } else {
1549
1.13M
      ms->offset = ms->eoffset + offset;
1550
1.13M
    }
1551
75.6M
  }
1552
75.8M
  if ((ms->flags & MAGIC_DEBUG) != 0) {
1553
0
    fprintf(stderr, "bb=[%p,%" SIZE_T_FORMAT "u,%"
1554
0
        SIZE_T_FORMAT "u], %d [b=%p,%"
1555
0
        SIZE_T_FORMAT "u,%" SIZE_T_FORMAT "u], [o=%#x, c=%d]\n",
1556
0
        bb->fbuf, bb->flen, bb->elen, ms->offset, b->fbuf,
1557
0
        b->flen, b->elen, offset, cont_level);
1558
0
  }
1559
75.8M
  return 0;
1560
75.8M
}
1561
1562
file_private int
1563
save_cont(struct magic_set *ms, struct cont *c)
1564
44.6k
{
1565
44.6k
  size_t len;
1566
44.6k
  *c = ms->c;
1567
44.6k
  len = c->len * sizeof(*c->li);
1568
44.6k
  ms->c.li = CAST(struct level_info *, malloc(len));
1569
44.6k
  if (ms->c.li == NULL) {
1570
0
    ms->c = *c;
1571
0
    return -1;
1572
0
  }
1573
44.6k
  memcpy(ms->c.li, c->li, len);
1574
44.6k
  return 0;
1575
44.6k
}
1576
1577
file_private void
1578
restore_cont(struct magic_set *ms, struct cont *c)
1579
44.6k
{
1580
44.6k
  free(ms->c.li);
1581
44.6k
  ms->c = *c;
1582
44.6k
}
1583
1584
file_private int
1585
mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
1586
    const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
1587
    int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
1588
    int *printed_something, int *need_separator, int *firstline, int *returnval,
1589
    int *found_match)
1590
75.8M
{
1591
75.8M
  uint32_t eoffset, offset = ms->offset;
1592
75.8M
  struct buffer bb;
1593
75.8M
  intmax_t lhs;
1594
75.8M
  file_pushbuf_t *pb;
1595
75.8M
  int rv, oneed_separator, in_type, nfound_match;
1596
75.8M
  char *rbuf;
1597
75.8M
  union VALUETYPE *p = &ms->ms_value;
1598
75.8M
  struct mlist ml, *mlp;
1599
75.8M
  struct cont c;
1600
1601
75.8M
  if (*indir_count >= ms->indir_max) {
1602
405
    file_error(ms, 0, "indirect count (%hu) exceeded",
1603
405
        *indir_count);
1604
405
    return -1;
1605
405
  }
1606
1607
75.8M
  if (*name_count >= ms->name_max) {
1608
10
    file_error(ms, 0, "name use count (%hu) exceeded",
1609
10
        *name_count);
1610
10
    return -1;
1611
10
  }
1612
1613
1614
1615
75.8M
  if (mcopy(ms, p, m->type, m->flag & INDIR, s,
1616
75.8M
      CAST(uint32_t, offset + o), CAST(uint32_t, nbytes), m) == -1)
1617
0
    return -1;
1618
1619
75.8M
  if ((ms->flags & MAGIC_DEBUG) != 0) {
1620
0
    fprintf(stderr, "mget(type=%d, flag=%#x, offset=%u, o=%"
1621
0
        SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
1622
0
        "u, il=%hu, nc=%hu)\n",
1623
0
        m->type, m->flag, offset, o, nbytes,
1624
0
        *indir_count, *name_count);
1625
0
    mdebug(offset, RCAST(char *, RCAST(void *, p)),
1626
0
        sizeof(union VALUETYPE));
1627
0
#ifndef COMPILE_ONLY
1628
0
    file_mdump(m);
1629
0
#endif
1630
0
  }
1631
1632
75.8M
  if (m->flag & INDIR) {
1633
93.1k
    intmax_t off = m->in_offset;
1634
93.1k
    const int sgn = m->in_op & FILE_OPSIGNED;
1635
93.1k
    if (m->in_op & FILE_OPINDIRECT) {
1636
691
      const union VALUETYPE *q = CAST(const union VALUETYPE *,
1637
691
          RCAST(const void *, s + offset + off));
1638
691
      int op;
1639
691
      switch (op = cvt_flip(m->in_type, flip)) {
1640
0
      case FILE_BYTE:
1641
0
        if (OFFSET_OOB(nbytes, offset + off, 1))
1642
0
          return 0;
1643
0
        off = SEXT(sgn,8,q->b);
1644
0
        break;
1645
0
      case FILE_SHORT:
1646
0
        if (OFFSET_OOB(nbytes, offset + off, 2))
1647
0
          return 0;
1648
0
        off = SEXT(sgn,16,q->h);
1649
0
        break;
1650
0
      case FILE_BESHORT:
1651
0
        if (OFFSET_OOB(nbytes, offset + off, 2))
1652
0
          return 0;
1653
0
        off = SEXT(sgn,16,BE16(q));
1654
0
        break;
1655
0
      case FILE_LESHORT:
1656
0
        if (OFFSET_OOB(nbytes, offset + off, 2))
1657
0
          return 0;
1658
0
        off = SEXT(sgn,16,LE16(q));
1659
0
        break;
1660
0
      case FILE_LONG:
1661
0
        if (OFFSET_OOB(nbytes, offset + off, 4))
1662
0
          return 0;
1663
0
        off = SEXT(sgn,32,q->l);
1664
0
        break;
1665
0
      case FILE_BELONG:
1666
0
      case FILE_BEID3:
1667
0
        if (OFFSET_OOB(nbytes, offset + off, 4))
1668
0
          return 0;
1669
0
        off = SEXT(sgn,32,BE32(q));
1670
0
        break;
1671
0
      case FILE_LEID3:
1672
691
      case FILE_LELONG:
1673
691
        if (OFFSET_OOB(nbytes, offset + off, 4))
1674
99
          return 0;
1675
592
        off = SEXT(sgn,32,LE32(q));
1676
592
        break;
1677
0
      case FILE_MELONG:
1678
0
        if (OFFSET_OOB(nbytes, offset + off, 4))
1679
0
          return 0;
1680
0
        off = SEXT(sgn,32,ME32(q));
1681
0
        break;
1682
0
      case FILE_BEQUAD:
1683
0
        if (OFFSET_OOB(nbytes, offset + off, 8))
1684
0
          return 0;
1685
0
        off = SEXT(sgn,64,BE64(q));
1686
0
        break;
1687
0
      case FILE_LEQUAD:
1688
0
        if (OFFSET_OOB(nbytes, offset + off, 8))
1689
0
          return 0;
1690
0
        off = SEXT(sgn,64,LE64(q));
1691
0
        break;
1692
0
      case FILE_OCTAL:
1693
0
        if (OFFSET_OOB(nbytes, offset, m->vallen))
1694
0
          return 0;
1695
0
        off = SEXT(sgn,64,strtoull(p->s, NULL, 8));
1696
0
        break;
1697
0
      default:
1698
0
        if ((ms->flags & MAGIC_DEBUG) != 0)
1699
0
          fprintf(stderr, "bad op=%d\n", op);
1700
0
        return 0;
1701
691
      }
1702
592
      if ((ms->flags & MAGIC_DEBUG) != 0)
1703
0
        fprintf(stderr, "indirect offs=%jd\n", off);
1704
592
    }
1705
93.0k
    switch (in_type = cvt_flip(m->in_type, flip)) {
1706
17.4k
    case FILE_BYTE:
1707
17.4k
      if (OFFSET_OOB(nbytes, offset, 1))
1708
24
        return 0;
1709
17.4k
      if (do_ops(ms, m, &offset, SEXT(sgn,8,p->b), off))
1710
0
        return 0;
1711
17.4k
      break;
1712
20.2k
    case FILE_BESHORT:
1713
20.2k
      if (OFFSET_OOB(nbytes, offset, 2))
1714
113
        return 0;
1715
20.1k
      if (do_ops(ms, m, &offset, SEXT(sgn,16,BE16(p)), off))
1716
0
        return 0;
1717
20.1k
      break;
1718
20.1k
    case FILE_LESHORT:
1719
4.58k
      if (OFFSET_OOB(nbytes, offset, 2))
1720
610
        return 0;
1721
3.97k
      if (do_ops(ms, m, &offset, SEXT(sgn,16,LE16(p)), off))
1722
0
        return 0;
1723
3.97k
      break;
1724
3.97k
    case FILE_SHORT:
1725
0
      if (OFFSET_OOB(nbytes, offset, 2))
1726
0
        return 0;
1727
0
      if (do_ops(ms, m, &offset, SEXT(sgn,16,p->h), off))
1728
0
        return 0;
1729
0
      break;
1730
4.06k
    case FILE_BELONG:
1731
4.96k
    case FILE_BEID3:
1732
4.96k
      if (OFFSET_OOB(nbytes, offset, 4))
1733
196
        return 0;
1734
4.77k
      lhs = BE32(p);
1735
4.77k
      if (in_type == FILE_BEID3)
1736
877
        lhs = cvt_id3(ms, CAST(uint32_t, lhs));
1737
4.77k
      if (do_ops(ms, m, &offset, SEXT(sgn,32,lhs), off))
1738
299
        return 0;
1739
4.47k
      break;
1740
42.9k
    case FILE_LELONG:
1741
42.9k
    case FILE_LEID3:
1742
42.9k
      if (OFFSET_OOB(nbytes, offset, 4))
1743
3.44k
        return 0;
1744
39.4k
      lhs = LE32(p);
1745
39.4k
      if (in_type == FILE_LEID3)
1746
0
        lhs = cvt_id3(ms, CAST(uint32_t, lhs));
1747
39.4k
      if (do_ops(ms, m, &offset, SEXT(sgn,32,lhs), off))
1748
443
        return 0;
1749
39.0k
      break;
1750
39.0k
    case FILE_MELONG:
1751
0
      if (OFFSET_OOB(nbytes, offset, 4))
1752
0
        return 0;
1753
0
      if (do_ops(ms, m, &offset, SEXT(sgn,32,ME32(p)), off))
1754
0
        return 0;
1755
0
      break;
1756
2.60k
    case FILE_LONG:
1757
2.60k
      if (OFFSET_OOB(nbytes, offset, 4))
1758
250
        return 0;
1759
2.35k
      if (do_ops(ms, m, &offset, SEXT(sgn,32,p->l), off))
1760
125
        return 0;
1761
2.22k
      break;
1762
2.22k
    case FILE_LEQUAD:
1763
191
      if (OFFSET_OOB(nbytes, offset, 8))
1764
0
        return 0;
1765
191
      if (do_ops(ms, m, &offset, SEXT(sgn,64,LE64(p)), off))  
1766
116
        return 0;
1767
75
      break;
1768
116
    case FILE_BEQUAD:
1769
116
      if (OFFSET_OOB(nbytes, offset, 8))
1770
0
        return 0;
1771
116
      if (do_ops(ms, m, &offset, SEXT(sgn,64,BE64(p)), off))
1772
67
        return 0;
1773
49
      break;
1774
49
    case FILE_OCTAL:
1775
0
      if (OFFSET_OOB(nbytes, offset, m->vallen))
1776
0
        return 0;
1777
0
      if(do_ops(ms, m, &offset,
1778
0
          SEXT(sgn,64,strtoull(p->s, NULL, 8)), off))
1779
0
        return 0;
1780
0
      break;
1781
0
    default:
1782
0
      if ((ms->flags & MAGIC_DEBUG) != 0)
1783
0
        fprintf(stderr, "bad in_type=%d\n", in_type);
1784
0
      return 0;
1785
93.0k
    }
1786
1787
87.3k
    if (m->flag & INDIROFFADD) {
1788
1.13k
      if (cont_level == 0) {
1789
0
        if ((ms->flags & MAGIC_DEBUG) != 0)
1790
0
          fprintf(stderr,
1791
0
              "indirect *zero* cont_level\n");
1792
0
        return 0;
1793
0
      }
1794
1.13k
      offset += ms->c.li[cont_level - 1].off;
1795
1.13k
      if (offset == 0) {
1796
93
        if ((ms->flags & MAGIC_DEBUG) != 0)
1797
0
          fprintf(stderr,
1798
0
              "indirect *zero* offset\n");
1799
93
        return 0;
1800
93
      }
1801
1.04k
      if ((ms->flags & MAGIC_DEBUG) != 0)
1802
0
        fprintf(stderr, "indirect +offs=%u\n", offset);
1803
1.04k
    }
1804
87.2k
    if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
1805
0
      return -1;
1806
87.2k
    ms->offset = offset;
1807
1808
87.2k
    if ((ms->flags & MAGIC_DEBUG) != 0) {
1809
0
      mdebug(offset, RCAST(char *, RCAST(void *, p)),
1810
0
          sizeof(union VALUETYPE));
1811
0
#ifndef COMPILE_ONLY
1812
0
      file_mdump(m);
1813
0
#endif
1814
0
    }
1815
87.2k
  }
1816
1817
  /* Verify we have enough data to match magic type */
1818
75.8M
  switch (m->type) {
1819
1.15M
  case FILE_BYTE:
1820
1.15M
    if (OFFSET_OOB(nbytes, offset, 1))
1821
92.2k
      return 0;
1822
1.06M
    break;
1823
1824
1.06M
  case FILE_SHORT:
1825
4.06M
  case FILE_BESHORT:
1826
6.50M
  case FILE_LESHORT:
1827
6.50M
    if (OFFSET_OOB(nbytes, offset, 2))
1828
430k
      return 0;
1829
6.07M
    break;
1830
1831
6.07M
  case FILE_LONG:
1832
11.0M
  case FILE_BELONG:
1833
15.8M
  case FILE_LELONG:
1834
15.8M
  case FILE_MELONG:
1835
15.8M
  case FILE_DATE:
1836
15.8M
  case FILE_BEDATE:
1837
15.8M
  case FILE_LEDATE:
1838
15.8M
  case FILE_MEDATE:
1839
15.8M
  case FILE_LDATE:
1840
15.8M
  case FILE_BELDATE:
1841
15.8M
  case FILE_LELDATE:
1842
15.8M
  case FILE_MELDATE:
1843
15.8M
  case FILE_FLOAT:
1844
15.8M
  case FILE_BEFLOAT:
1845
15.8M
  case FILE_LEFLOAT:
1846
15.8M
    if (OFFSET_OOB(nbytes, offset, 4))
1847
1.50M
      return 0;
1848
14.3M
    break;
1849
1850
14.3M
  case FILE_DOUBLE:
1851
165
  case FILE_BEDOUBLE:
1852
425
  case FILE_LEDOUBLE:
1853
425
    if (OFFSET_OOB(nbytes, offset, 8))
1854
180
      return 0;
1855
245
    break;
1856
1857
157k
  case FILE_GUID:
1858
157k
    if (OFFSET_OOB(nbytes, offset, 16))
1859
16.4k
      return 0;
1860
140k
    break;
1861
1862
49.5M
  case FILE_STRING:
1863
49.5M
  case FILE_PSTRING:
1864
50.2M
  case FILE_SEARCH:
1865
50.2M
  case FILE_OCTAL:
1866
50.2M
    if (OFFSET_OOB(nbytes, offset, m->vallen))
1867
8.95M
      return 0;
1868
41.2M
    break;
1869
1870
41.2M
  case FILE_REGEX:
1871
161k
    if (nbytes < offset)
1872
817
      return 0;
1873
160k
    break;
1874
1875
160k
  case FILE_INDIRECT:
1876
16.2k
    if (m->str_flags & INDIRECT_RELATIVE)
1877
12.5k
      offset += CAST(uint32_t, o);
1878
16.2k
    if (offset == 0)
1879
596
      return 0;
1880
1881
15.6k
    if (nbytes < offset)
1882
1.59k
      return 0;
1883
1884
14.0k
    if ((pb = file_push_buffer(ms)) == NULL)
1885
300
      return -1;
1886
1887
13.7k
    (*indir_count)++;
1888
13.7k
    bb = *b;
1889
13.7k
    bb.fbuf = s + offset;
1890
13.7k
    bb.flen = nbytes - offset;
1891
13.7k
    bb.ebuf = NULL;
1892
13.7k
    bb.elen = 0;
1893
13.7k
    rv = -1;
1894
16.2k
    for (mlp = ms->mlist[0]->next; mlp != ms->mlist[0];
1895
13.7k
        mlp = mlp->next)
1896
13.7k
    {
1897
13.7k
      if ((rv = match(ms, mlp->magic, mlp->magic_rxcomp,
1898
13.7k
          mlp->nmagic, &bb, 0, BINTEST, text, 0, indir_count,
1899
13.7k
          name_count, printed_something, need_separator,
1900
13.7k
          firstline, NULL, NULL)) != 0)
1901
11.2k
        break;
1902
13.7k
    }
1903
13.7k
    buffer_fini(&bb);
1904
1905
13.7k
    if ((ms->flags & MAGIC_DEBUG) != 0)
1906
0
      fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
1907
1908
13.7k
    rbuf = file_pop_buffer(ms, pb);
1909
13.7k
    if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
1910
995
      return -1;
1911
1912
12.7k
    if (rv == 1) {
1913
10.2k
      if ((ms->flags & MAGIC_NODESC) == 0 &&
1914
10.2k
          file_printf(ms, F(ms, m->desc, "%u"), offset) == -1)
1915
0
      {
1916
0
        free(rbuf);
1917
0
        return -1;
1918
0
      }
1919
10.2k
      if (file_printf(ms, "%s", rbuf) == -1) {
1920
93
        free(rbuf);
1921
93
        return -1;
1922
93
      }
1923
10.2k
    }
1924
12.6k
    free(rbuf);
1925
12.6k
    return rv;
1926
1927
51.0k
  case FILE_USE:
1928
51.0k
    if (nbytes < offset)
1929
6.43k
      return 0;
1930
44.6k
    rbuf = m->value.s;
1931
44.6k
    if (*rbuf == '^') {
1932
238
      rbuf++;
1933
238
      flip = !flip;
1934
238
    }
1935
44.6k
    if (file_magicfind(ms, rbuf, &ml) == -1) {
1936
0
      file_error(ms, 0, "cannot find entry `%s'", rbuf);
1937
0
      return -1;
1938
0
    }
1939
44.6k
    if (save_cont(ms, &c) == -1) {
1940
0
      file_error(ms, errno, "can't allocate continuation");
1941
0
      return -1;
1942
0
    }
1943
1944
44.6k
    oneed_separator = *need_separator;
1945
44.6k
    if (m->flag & NOSPACE)
1946
5.81k
      *need_separator = 0;
1947
1948
44.6k
    nfound_match = 0;
1949
44.6k
    (*name_count)++;
1950
44.6k
    eoffset = ms->eoffset;
1951
44.6k
    rv = match(ms, ml.magic, ml.magic_rxcomp, ml.nmagic, b,
1952
44.6k
        offset + o, mode, text, flip, indir_count, name_count,
1953
44.6k
        printed_something, need_separator, firstline, returnval,
1954
44.6k
        &nfound_match);
1955
44.6k
    ms->ms_value.q = nfound_match;
1956
44.6k
    (*name_count)--;
1957
44.6k
    *found_match |= nfound_match;
1958
1959
44.6k
    restore_cont(ms, &c);
1960
1961
44.6k
    if (rv != 1)
1962
3.07k
        *need_separator = oneed_separator;
1963
44.6k
    ms->offset = offset;
1964
44.6k
    ms->eoffset = eoffset;
1965
44.6k
    return rv || *found_match;
1966
1967
44.6k
  case FILE_NAME:
1968
44.6k
    if (ms->flags & MAGIC_NODESC)
1969
0
      return 1;
1970
44.6k
    if (file_printf(ms, "%s", m->desc) == -1)
1971
0
      return -1;
1972
44.6k
    return 1;
1973
306k
  case FILE_DER:
1974
312k
  case FILE_DEFAULT: /* nothing to check */
1975
313k
  case FILE_CLEAR:
1976
1.62M
  default:
1977
1.62M
    break;
1978
75.8M
  }
1979
64.7M
  if (!mconvert(ms, m, flip))
1980
18
    return 0;
1981
64.7M
  return 1;
1982
64.7M
}
1983
1984
file_private uint64_t
1985
file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen,
1986
    uint32_t flags)
1987
196M
{
1988
  /*
1989
   * Convert the source args to unsigned here so that (1) the
1990
   * compare will be unsigned as it is in strncmp() and (2) so
1991
   * the ctype functions will work correctly without extra
1992
   * casting.
1993
   */
1994
196M
  const unsigned char *a = RCAST(const unsigned char *, s1);
1995
196M
  const unsigned char *b = RCAST(const unsigned char *, s2);
1996
196M
  uint32_t ws = flags & (STRING_COMPACT_WHITESPACE |
1997
196M
      STRING_COMPACT_OPTIONAL_WHITESPACE);
1998
196M
  const unsigned char *eb = b + (ws ? maxlen : len);
1999
196M
  uint64_t v;
2000
2001
  /*
2002
   * What we want here is v = strncmp(s1, s2, len),
2003
   * but ignoring any nulls.
2004
   */
2005
196M
  v = 0;
2006
196M
  len++;
2007
196M
  if (0L == flags) { /* normal string: do it fast */
2008
39.4M
    while (--len > 0)
2009
39.4M
      if ((v = *b++ - *a++) != '\0')
2010
38.8M
        break;
2011
38.8M
  }
2012
158M
  else { /* combine the others */
2013
158M
    while (--len > 0) {
2014
158M
      if (b >= eb) {
2015
202k
        v = 1;
2016
202k
        break;
2017
202k
      }
2018
158M
      if ((flags & STRING_IGNORE_LOWERCASE) &&
2019
158M
          islower(*a)) {
2020
1.98M
        if ((v = tolower(*b++) - *a++) != '\0')
2021
1.95M
          break;
2022
1.98M
      }
2023
156M
      else if ((flags & STRING_IGNORE_UPPERCASE) &&
2024
156M
          isupper(*a)) {
2025
10.9k
        if ((v = toupper(*b++) - *a++) != '\0')
2026
10.8k
          break;
2027
10.9k
      }
2028
156M
      else if ((flags & STRING_COMPACT_WHITESPACE) &&
2029
156M
          isspace(*a)) {
2030
784k
        a++;
2031
784k
        if (isspace(*b)) {
2032
214k
          b++;
2033
214k
          if (!isspace(*a))
2034
6.08G
            while (b < eb && isspace(*b))
2035
6.08G
              b++;
2036
214k
        }
2037
570k
        else {
2038
570k
          v = 1;
2039
570k
          break;
2040
570k
        }
2041
784k
      }
2042
155M
      else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
2043
155M
          isspace(*a)) {
2044
3.37k
        a++;
2045
9.46k
        while (b < eb && isspace(*b))
2046
6.09k
          b++;
2047
3.37k
      }
2048
155M
      else {
2049
155M
        if ((v = *b++ - *a++) != '\0')
2050
155M
          break;
2051
155M
      }
2052
158M
    }
2053
158M
    if (len == 0 && v == 0 && (flags & STRING_FULL_WORD)) {
2054
184
      if (*b && !isspace(*b))
2055
91
        v = 1;
2056
184
    }
2057
158M
  }
2058
196M
  return v;
2059
196M
}
2060
2061
file_private uint64_t
2062
file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
2063
    uint32_t flags)
2064
47.8k
{
2065
  /*
2066
   * XXX - The 16-bit string compare probably needs to be done
2067
   * differently, especially if the flags are to be supported.
2068
   * At the moment, I am unsure.
2069
   */
2070
47.8k
  flags = 0;
2071
47.8k
  return file_strncmp(a, b, len, maxlen, flags);
2072
47.8k
}
2073
2074
file_private file_regex_t *
2075
alloc_regex(struct magic_set *ms, struct magic *m)
2076
143
{
2077
143
  int rc;
2078
143
  file_regex_t *rx = CAST(file_regex_t *, malloc(sizeof(*rx)));
2079
2080
143
  if (rx == NULL) {
2081
0
    file_error(ms, errno, "can't allocate %" SIZE_T_FORMAT
2082
0
        "u bytes", sizeof(*rx));
2083
0
    return NULL;
2084
0
  }
2085
2086
143
  rc = file_regcomp(ms, rx, m->value.s, REG_EXTENDED | REG_NEWLINE |
2087
143
      ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
2088
143
  if (rc == 0)
2089
143
    return rx;
2090
2091
0
  free(rx);
2092
0
  return NULL;
2093
143
}
2094
2095
file_private int
2096
magiccheck(struct magic_set *ms, struct magic *m, file_regex_t **m_cache)
2097
64.8M
{
2098
64.8M
  uint64_t l = m->value.q;
2099
64.8M
  uint64_t v;
2100
64.8M
  float fl, fv;
2101
64.8M
  double dl, dv;
2102
64.8M
  int matched;
2103
64.8M
  union VALUETYPE *p = &ms->ms_value;
2104
2105
64.8M
  switch (m->type) {
2106
1.06M
  case FILE_BYTE:
2107
1.06M
    v = p->b;
2108
1.06M
    break;
2109
2110
734k
  case FILE_SHORT:
2111
3.83M
  case FILE_BESHORT:
2112
6.07M
  case FILE_LESHORT:
2113
6.07M
  case FILE_MSDOSDATE:
2114
6.07M
  case FILE_LEMSDOSDATE:
2115
6.07M
  case FILE_BEMSDOSDATE:
2116
6.07M
  case FILE_MSDOSTIME:
2117
6.07M
  case FILE_LEMSDOSTIME:
2118
6.07M
  case FILE_BEMSDOSTIME:
2119
6.07M
    v = p->h;
2120
6.07M
    break;
2121
2122
1.08M
  case FILE_LONG:
2123
10.1M
  case FILE_BELONG:
2124
14.3M
  case FILE_LELONG:
2125
14.3M
  case FILE_MELONG:
2126
14.3M
  case FILE_DATE:
2127
14.3M
  case FILE_BEDATE:
2128
14.3M
  case FILE_LEDATE:
2129
14.3M
  case FILE_MEDATE:
2130
14.3M
  case FILE_LDATE:
2131
14.3M
  case FILE_BELDATE:
2132
14.3M
  case FILE_LELDATE:
2133
14.3M
  case FILE_MELDATE:
2134
14.3M
    v = p->l;
2135
14.3M
    break;
2136
2137
47.6k
  case FILE_QUAD:
2138
625k
  case FILE_LEQUAD:
2139
1.25M
  case FILE_BEQUAD:
2140
1.25M
  case FILE_QDATE:
2141
1.25M
  case FILE_BEQDATE:
2142
1.25M
  case FILE_LEQDATE:
2143
1.25M
  case FILE_QLDATE:
2144
1.25M
  case FILE_BEQLDATE:
2145
1.25M
  case FILE_LEQLDATE:
2146
1.26M
  case FILE_QWDATE:
2147
1.26M
  case FILE_BEQWDATE:
2148
1.26M
  case FILE_LEQWDATE:
2149
1.26M
  case FILE_OFFSET:
2150
1.26M
    v = p->q;
2151
1.26M
    break;
2152
2153
0
  case FILE_FLOAT:
2154
0
  case FILE_BEFLOAT:
2155
1.18k
  case FILE_LEFLOAT:
2156
1.18k
    fl = m->value.f;
2157
1.18k
    fv = p->f;
2158
1.18k
    switch (m->reln) {
2159
333
    case 'x':
2160
333
      matched = 1;
2161
333
      break;
2162
2163
0
    case '!':
2164
0
      matched = isunordered(fl, fv) ? 1 : fv != fl;
2165
0
      break;
2166
2167
0
    case '=':
2168
0
      matched = isunordered(fl, fv) ? 0 : fv == fl;
2169
0
      break;
2170
2171
855
    case '>':
2172
855
      matched = isgreater(fv, fl);
2173
855
      break;
2174
2175
0
    case '<':
2176
0
      matched = isless(fv, fl);
2177
0
      break;
2178
2179
0
    default:
2180
0
      file_magerror(ms, "cannot happen with float: "
2181
0
          "invalid relation `%c'", m->reln);
2182
0
      return -1;
2183
1.18k
    }
2184
1.18k
    return matched;
2185
2186
0
  case FILE_DOUBLE:
2187
106
  case FILE_BEDOUBLE:
2188
245
  case FILE_LEDOUBLE:
2189
245
    dl = m->value.d;
2190
245
    dv = p->d;
2191
245
    switch (m->reln) {
2192
64
    case 'x':
2193
64
      matched = 1;
2194
64
      break;
2195
2196
0
    case '!':
2197
0
      matched = isunordered(dv, dl) ? 1 : dv != dl;
2198
0
      break;
2199
2200
181
    case '=':
2201
181
      matched = isunordered(dv, dl) ? 0 : dv == dl;
2202
181
      break;
2203
2204
0
    case '>':
2205
0
      matched = isgreater(dv, dl);
2206
0
      break;
2207
2208
0
    case '<':
2209
0
      matched = isless(dv, dl);
2210
0
      break;
2211
2212
0
    default:
2213
0
      file_magerror(ms, "cannot happen with double: "
2214
0
          "invalid relation `%c'", m->reln);
2215
0
      return -1;
2216
245
    }
2217
245
    return matched;
2218
2219
6.52k
  case FILE_DEFAULT:
2220
7.28k
  case FILE_CLEAR:
2221
7.28k
    l = 0;
2222
7.28k
    v = 0;
2223
7.28k
    break;
2224
2225
40.8M
  case FILE_STRING:
2226
40.8M
  case FILE_PSTRING:
2227
40.8M
  case FILE_OCTAL:
2228
40.8M
    l = 0;
2229
40.8M
    v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen),
2230
40.8M
        sizeof(p->s), m->str_flags);
2231
40.8M
    break;
2232
2233
126
  case FILE_BESTRING16:
2234
47.8k
  case FILE_LESTRING16:
2235
47.8k
    l = 0;
2236
47.8k
    v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen),
2237
47.8k
        sizeof(p->s), m->str_flags);
2238
47.8k
    break;
2239
2240
399k
  case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
2241
399k
    size_t slen;
2242
399k
    size_t idx;
2243
2244
399k
    if (ms->search.s == NULL)
2245
0
      return 0;
2246
2247
399k
    slen = MIN(m->vallen, sizeof(m->value.s));
2248
399k
    l = 0;
2249
399k
    v = 0;
2250
399k
    if ((ms->flags & MAGIC_DEBUG) != 0) {
2251
0
      size_t xlen = ms->search.s_len > 100 ? 100
2252
0
          : ms->search.s_len;
2253
2254
0
      fprintf(stderr, "search: [");
2255
0
      file_showstr(stderr, ms->search.s, xlen);
2256
0
      fprintf(stderr, "%s] for [", ms->search.s_len == xlen
2257
0
          ? "" : "...");
2258
0
      file_showstr(stderr, m->value.s, slen);
2259
0
    }
2260
399k
#ifdef HAVE_MEMMEM
2261
399k
    if (slen > 0 && m->str_flags == 0) {
2262
225k
      const char *found;
2263
225k
      idx = m->str_range + slen;
2264
225k
      if (m->str_range == 0 || ms->search.s_len < idx)
2265
92.6k
        idx = ms->search.s_len;
2266
225k
      found = CAST(const char *, memmem(ms->search.s, idx,
2267
225k
          m->value.s, slen));
2268
225k
      if ((ms->flags & MAGIC_DEBUG) != 0) {
2269
0
        fprintf(stderr, "] %sfound\n",
2270
0
            found ? "" : "not ");
2271
0
      }
2272
225k
      if (!found) {
2273
224k
        v = 1;
2274
224k
        break;
2275
224k
      }
2276
1.51k
      idx = found - ms->search.s;
2277
1.51k
      ms->search.offset += idx;
2278
1.51k
      ms->search.rm_len = ms->search.s_len - idx;
2279
1.51k
      break;
2280
225k
    }
2281
173k
#endif
2282
2283
156M
    for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
2284
156M
      if (slen + idx > ms->search.s_len) {
2285
95.0k
        v = 1;
2286
95.0k
        break;
2287
95.0k
      }
2288
2289
155M
      v = file_strncmp(m->value.s, ms->search.s + idx, slen,
2290
155M
          ms->search.s_len - idx, m->str_flags);
2291
155M
      if (v == 0) { /* found match */
2292
227
        ms->search.offset += idx;
2293
227
        ms->search.rm_len = ms->search.s_len - idx;
2294
227
        break;
2295
227
      }
2296
155M
    }
2297
173k
    if ((ms->flags & MAGIC_DEBUG) != 0) {
2298
0
      fprintf(stderr, "] %sfound\n", v == 0 ? "" : "not ");
2299
0
    }
2300
173k
    break;
2301
399k
  }
2302
160k
  case FILE_REGEX: {
2303
160k
    int rc;
2304
160k
    file_regex_t *rx = *m_cache;
2305
160k
    const char *search;
2306
160k
    regmatch_t pmatch;
2307
160k
    size_t slen = ms->search.s_len;
2308
160k
    char *copy;
2309
2310
160k
    if (ms->search.s == NULL)
2311
31
      return 0;
2312
2313
160k
    if (rx == NULL) {
2314
143
      rx = *m_cache = alloc_regex(ms, m);
2315
143
      if (rx == NULL)
2316
0
        return -1;
2317
143
    }
2318
160k
    l = 0;
2319
160k
    if (slen != 0) {
2320
158k
        copy = CAST(char *, malloc(slen));
2321
158k
        if (copy == NULL)  {
2322
0
      file_error(ms, errno,
2323
0
          "can't allocate %" SIZE_T_FORMAT "u bytes",
2324
0
          slen);
2325
0
      return -1;
2326
0
        }
2327
158k
        memcpy(copy, ms->search.s, slen);
2328
158k
        copy[--slen] = '\0';
2329
158k
        search = copy;
2330
158k
    } else {
2331
1.40k
        search = CCAST(char *, "");
2332
1.40k
        copy = NULL;
2333
1.40k
    }
2334
160k
    rc = file_regexec(ms, rx, RCAST(const char *, search),
2335
160k
        1, &pmatch, 0);
2336
160k
    free(copy);
2337
160k
    switch (rc) {
2338
2.02k
    case 0:
2339
2.02k
      ms->search.s += CAST(int, pmatch.rm_so);
2340
2.02k
      ms->search.offset += CAST(size_t, pmatch.rm_so);
2341
2.02k
      ms->search.rm_len = CAST(size_t,
2342
2.02k
          pmatch.rm_eo - pmatch.rm_so);
2343
2.02k
      v = 0;
2344
2.02k
      break;
2345
2346
158k
    case REG_NOMATCH:
2347
158k
      v = 1;
2348
158k
      break;
2349
2350
0
    default:
2351
0
      return -1;
2352
160k
    }
2353
160k
    break;
2354
160k
  }
2355
160k
  case FILE_USE:
2356
42.5k
    return ms->ms_value.q != 0;
2357
44.6k
  case FILE_NAME:
2358
54.8k
  case FILE_INDIRECT:
2359
54.8k
    return 1;
2360
306k
  case FILE_DER:
2361
306k
    matched = der_cmp(ms, m);
2362
306k
    if (matched == -1) {
2363
103k
      if ((ms->flags & MAGIC_DEBUG) != 0) {
2364
0
        (void) fprintf(stderr,
2365
0
            "EOF comparing DER entries\n");
2366
0
      }
2367
103k
      return 0;
2368
103k
    }
2369
202k
    return matched;
2370
140k
  case FILE_GUID:
2371
140k
    l = 0;
2372
140k
    v = memcmp(m->value.guid, p->guid, sizeof(p->guid));
2373
140k
    break;
2374
0
  default:
2375
0
    file_magerror(ms, "invalid type %d in magiccheck()", m->type);
2376
0
    return -1;
2377
64.8M
  }
2378
2379
64.3M
  v = file_signextend(ms, m, v);
2380
2381
64.3M
  switch (m->reln) {
2382
64.3k
  case 'x':
2383
64.3k
    if ((ms->flags & MAGIC_DEBUG) != 0)
2384
0
      (void) fprintf(stderr, "%" INT64_T_FORMAT
2385
0
          "u == *any* = 1", CAST(unsigned long long, v));
2386
64.3k
    matched = 1;
2387
64.3k
    break;
2388
2389
45.6k
  case '!':
2390
45.6k
    matched = v != l;
2391
45.6k
    if ((ms->flags & MAGIC_DEBUG) != 0)
2392
0
      (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
2393
0
          INT64_T_FORMAT "u = %d",
2394
0
          CAST(unsigned long long, v),
2395
0
          CAST(unsigned long long, l), matched);
2396
45.6k
    break;
2397
2398
63.8M
  case '=':
2399
63.8M
    matched = v == l;
2400
63.8M
    if ((ms->flags & MAGIC_DEBUG) != 0)
2401
0
      (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
2402
0
          INT64_T_FORMAT "u = %d",
2403
0
          CAST(unsigned long long, v),
2404
0
          CAST(unsigned long long, l), matched);
2405
63.8M
    break;
2406
2407
160k
  case '>':
2408
160k
    if (m->flag & UNSIGNED) {
2409
125k
      matched = v > l;
2410
125k
      if ((ms->flags & MAGIC_DEBUG) != 0)
2411
0
        (void) fprintf(stderr, "%" INT64_T_FORMAT
2412
0
            "u > %" INT64_T_FORMAT "u = %d",
2413
0
            CAST(unsigned long long, v),
2414
0
            CAST(unsigned long long, l), matched);
2415
125k
    }
2416
34.2k
    else {
2417
34.2k
      matched = CAST(int64_t, v) > CAST(int64_t, l);
2418
34.2k
      if ((ms->flags & MAGIC_DEBUG) != 0)
2419
0
        (void) fprintf(stderr, "%" INT64_T_FORMAT
2420
0
            "d > %" INT64_T_FORMAT "d = %d",
2421
0
            CAST(long long, v),
2422
0
            CAST(long long, l), matched);
2423
34.2k
    }
2424
160k
    break;
2425
2426
225k
  case '<':
2427
225k
    if (m->flag & UNSIGNED) {
2428
191k
      matched = v < l;
2429
191k
      if ((ms->flags & MAGIC_DEBUG) != 0)
2430
0
        (void) fprintf(stderr, "%" INT64_T_FORMAT
2431
0
            "u < %" INT64_T_FORMAT "u = %d",
2432
0
            CAST(unsigned long long, v),
2433
0
            CAST(unsigned long long, l), matched);
2434
191k
    }
2435
34.1k
    else {
2436
34.1k
      matched = CAST(int64_t, v) < CAST(int64_t, l);
2437
34.1k
      if ((ms->flags & MAGIC_DEBUG) != 0)
2438
0
        (void) fprintf(stderr, "%" INT64_T_FORMAT
2439
0
            "d < %" INT64_T_FORMAT "d = %d",
2440
0
             CAST(long long, v),
2441
0
             CAST(long long, l), matched);
2442
34.1k
    }
2443
225k
    break;
2444
2445
31.0k
  case '&':
2446
31.0k
    matched = (v & l) == l;
2447
31.0k
    if ((ms->flags & MAGIC_DEBUG) != 0)
2448
0
      (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
2449
0
          INT64_T_FORMAT "x) == %" INT64_T_FORMAT
2450
0
          "x) = %d", CAST(unsigned long long, v),
2451
0
          CAST(unsigned long long, l),
2452
0
          CAST(unsigned long long, l),
2453
0
          matched);
2454
31.0k
    break;
2455
2456
572
  case '^':
2457
572
    matched = (v & l) != l;
2458
572
    if ((ms->flags & MAGIC_DEBUG) != 0)
2459
0
      (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
2460
0
          INT64_T_FORMAT "x) != %" INT64_T_FORMAT
2461
0
          "x) = %d", CAST(unsigned long long, v),
2462
0
          CAST(unsigned long long, l),
2463
0
          CAST(unsigned long long, l), matched);
2464
572
    break;
2465
2466
0
  default:
2467
0
    file_magerror(ms, "cannot happen: invalid relation `%c'",
2468
0
        m->reln);
2469
0
    return -1;
2470
64.3M
  }
2471
64.3M
  if ((ms->flags & MAGIC_DEBUG) != 0) {
2472
0
    (void) fprintf(stderr, " strength=%zu\n",
2473
0
        file_magic_strength(m, 1));
2474
0
  }
2475
2476
64.3M
  return matched;
2477
64.3M
}
2478
2479
file_private int
2480
handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
2481
539k
{
2482
539k
  if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
2483
0
    if (print_sep(ms, firstline) == -1)
2484
0
      return -1;
2485
0
    if (file_printf(ms, "%.8s", m->apple) == -1)
2486
0
      return -1;
2487
0
    return 1;
2488
0
  }
2489
539k
  if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) {
2490
0
    if (print_sep(ms, firstline) == -1)
2491
0
      return -1;
2492
0
    if (file_printf(ms, "%s", m->ext) == -1)
2493
0
      return -1;
2494
0
    return 1;
2495
0
  }
2496
539k
  if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
2497
0
    char buf[1024];
2498
0
    const char *p;
2499
0
    if (print_sep(ms, firstline) == -1)
2500
0
      return -1;
2501
0
    if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1)
2502
0
      p = m->mimetype;
2503
0
    else
2504
0
      p = buf;
2505
0
    if (file_printf(ms, "%s", p) == -1)
2506
0
      return -1;
2507
0
    return 1;
2508
0
  }
2509
539k
  return 0;
2510
539k
}
2511
2512
file_private int
2513
print_sep(struct magic_set *ms, int firstline)
2514
37.5k
{
2515
37.5k
  if (firstline)
2516
9.49k
    return 0;
2517
  /*
2518
   * we found another match
2519
   * put a newline and '-' to do some simple formatting
2520
   */
2521
28.0k
  return file_separator(ms);
2522
37.5k
}