Rizin
unix-like reverse engineering framework and cli tools
apprentice.c File Reference
#include <rz_userconf.h>
#include <rz_util.h>
#include <ctype.h>
#include "file.h"
#include "patchlevel.h"
#include "mdump.c"

Go to the source code of this file.

Classes

struct  rz_magic_entry
 
struct  type_tbl_s
 

Macros

#define QUICK   0
 
#define EATAB
 
#define LOWCASE(l)   (isupper((ut8)(l)) ? tolower((ut8)(l)) : (l))
 
#define MAP_FILE   0
 
#define XX(s)   s, (sizeof(s) - 1)
 
#define XX_NULL   "", 0
 
#define MULT   10
 
#define SYMLEN   4 /* strlen("text") */
 
#define ALLOC_CHUNK   (size_t)10
 
#define ALLOC_INCR   (size_t)200
 
#define RET   1
 

Functions

static int getvalue (RzMagic *ms, struct rz_magic *, const char **, int)
 
static int hextoint (int)
 
static const char * getstr (RzMagic *, const char *, char *, int, int *, int)
 
static int parse (RzMagic *, struct rz_magic_entry **, ut32 *, const char *, size_t, int)
 
static int parse_mime (RzMagic *, struct rz_magic_entry **, ut32 *, const char *)
 
static void eatsize (const char **)
 
static int apprentice_1 (RzMagic *, const char *, int, struct mlist *)
 
static size_t apprentice_r_magic_strength (const struct rz_magic *)
 
static int apprentice_sort (const void *, const void *)
 
static int apprentice_load (RzMagic *, struct rz_magic **, ut32 *, const char *, int)
 
static void byteswap (struct rz_magic *, ut32)
 
static void bs1 (struct rz_magic *)
 
static ut16 swap2 (ut16)
 
static ut32 swap4 (ut32)
 
static ut64 swap8 (ut64)
 
static char * mkdbname (const char *, int)
 
static int apprentice_map (RzMagic *, struct rz_magic **, ut32 *, const char *)
 
static int apprentice_compile (RzMagic *, struct rz_magic **, ut32 *, const char *)
 
static int check_format_type (const char *, int)
 
static int check_format (RzMagic *, struct rz_magic *)
 
static int get_op (char)
 
static int get_type (const char *l, const char **t)
 
static void init_file_tables (void)
 
void file_delmagic (struct rz_magic *p, int type, size_t entries)
 
struct mlist * file_apprentice (RzMagic *ms, const char *fn, int action)
 
static void set_test_type (struct rz_magic *mstart, struct rz_magic *m)
 
static const char * bgets (char *line, size_t line_sz, const char *data)
 
static void load_b (RzMagic *ms, int action, const char *data, int *errs, struct rz_magic_entry **marray, ut32 *marraycount)
 
static void load_1 (RzMagic *ms, int action, const char *file, int *errs, struct rz_magic_entry **marray, ut32 *marraycount)
 
ut64 file_signextend (RzMagic *ms, struct rz_magic *m, ut64 v)
 
static int string_modifier_check (RzMagic *ms, struct rz_magic *m)
 
static int get_cond (const char *l, const char **t)
 
static int check_cond (RzMagic *ms, int cond, ut32 cont_level)
 
void file_showstr (FILE *fp, const char *s, size_t len)
 

Variables

static int magic_file_formats [FILE_NAMES_SIZE]
 
static const size_t file_nformats = FILE_NAMES_SIZE
 
static const char * magic_file_names [FILE_NAMES_SIZE]
 
static const size_t file_nnames = FILE_NAMES_SIZE
 
static size_t maxmagic = 0
 
static size_t magicsize = sizeof(struct rz_magic)
 
static const char usg_hdr [] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"
 
static const char mime_marker [] = "!:mime"
 
static const size_t mime_marker_len = sizeof(mime_marker) - 1
 
static const struct type_tbl_s type_tbl []
 
static const ut32 ar []
 
static const char ext [] = ".mgc"
 

Macro Definition Documentation

◆ ALLOC_CHUNK

#define ALLOC_CHUNK   (size_t)10

◆ ALLOC_INCR

#define ALLOC_INCR   (size_t)200

◆ EATAB

#define EATAB
Value:
{ \
while (isascii((ut8)*l) && isspace((ut8)*l)) { \
l++; \
} \
}
uint8_t ut8
Definition: lh5801.h:11
#define isspace(c)
Definition: safe-ctype.h:141

Definition at line 57 of file apprentice.c.

◆ LOWCASE

#define LOWCASE (   l)    (isupper((ut8)(l)) ? tolower((ut8)(l)) : (l))

Definition at line 63 of file apprentice.c.

◆ MAP_FILE

#define MAP_FILE   0

Definition at line 66 of file apprentice.c.

◆ MULT

#define MULT   10

◆ QUICK

#define QUICK   0

Definition at line 46 of file apprentice.c.

◆ RET

#define RET   1

◆ SYMLEN

#define SYMLEN   4 /* strlen("text") */

◆ XX

#define XX (   s)    s, (sizeof(s) - 1)

◆ XX_NULL

#define XX_NULL   "", 0

Function Documentation

◆ apprentice_1()

static int apprentice_1 ( RzMagic *  ms,
const char *  fn,
int  action,
struct mlist *  mlist 
)
static

Definition at line 193 of file apprentice.c.

193  {
194  struct rz_magic *magic = NULL;
195  ut32 nmagic = 0;
196  struct mlist *ml;
197  int rv = -1;
198  int mapped;
199 
200  if (!ms) {
201  return -1;
202  }
203  ms->haderr = 0;
204  if (magicsize != FILE_MAGICSIZE) {
205  file_error(ms, 0, "magic element size %lu != %lu",
206  (unsigned long)(size_t)sizeof(*magic),
207  (unsigned long)FILE_MAGICSIZE);
208  return -1;
209  }
210 
211  ms->file = fn; // fix use of ms->file before being initialized
212  if (action == FILE_COMPILE) {
213  rv = apprentice_load(ms, &magic, &nmagic, fn, action);
214  if (rv != 0) {
215  return -1;
216  }
217  rv = apprentice_compile(ms, &magic, &nmagic, fn);
218  free(magic);
219  return rv;
220  }
221 
222  if ((rv = apprentice_map(ms, &magic, &nmagic, fn)) == -1) {
223  // if (ms->flags & RZ_MAGIC_CHECK)
224  // file_magwarn(ms, "using regular magic file `%s'", fn);
225  rv = apprentice_load(ms, &magic, &nmagic, fn, action);
226  if (rv != 0) {
227  return -1;
228  }
229  }
230 
231  mapped = rv;
232 
233  if (!magic) {
234  file_delmagic(magic, mapped, nmagic);
235  return -1;
236  }
237 
238  if (!(ml = malloc(sizeof(*ml)))) {
239  file_delmagic(magic, mapped, nmagic);
240  file_oomem(ms, sizeof(*ml));
241  return -1;
242  }
243 
244  ml->magic = magic;
245  ml->nmagic = nmagic;
246  ml->mapped = mapped;
247 
248  mlist->prev->next = ml;
249  ml->prev = mlist->prev;
250  ml->next = mlist;
251  mlist->prev = ml;
252  return 0;
253 }
static int apprentice_map(RzMagic *, struct rz_magic **, ut32 *, const char *)
Definition: apprentice.c:1836
static size_t magicsize
Definition: apprentice.c:103
static int apprentice_compile(RzMagic *, struct rz_magic **, ut32 *, const char *)
Definition: apprentice.c:1942
static int apprentice_load(RzMagic *, struct rz_magic **, ut32 *, const char *, int)
Definition: apprentice.c:593
void file_delmagic(struct rz_magic *p, int type, size_t entries)
Definition: apprentice.c:255
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
void file_oomem(struct rz_magic_set *, size_t)
void file_error(struct rz_magic_set *, int, const char *,...)
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * malloc(size_t size)
Definition: malloc.c:123
static const char struct stat static buf struct stat static buf static idle const char static path static fd const char static len const void static prot const char struct module static image struct kernel_sym static table unsigned char static buf static fsuid unsigned struct dirent unsigned static count const struct iovec static count static pid const void static len static flags const struct sched_param static p static pid static policy struct timespec static tp static suid unsigned fn
Definition: sflib.h:186

References test-lz4-speed::action, apprentice_compile(), apprentice_load(), apprentice_map(), file_delmagic(), file_error(), file_oomem(), fn, free(), magicsize, malloc(), and NULL.

Referenced by file_apprentice().

◆ apprentice_compile()

static int apprentice_compile ( RzMagic *  ms,
struct rz_magic **  magicp,
ut32 nmagicp,
const char *  fn 
)
static

Definition at line 1942 of file apprentice.c.

1942  {
1943  int fd;
1944  char *dbname;
1945  int rv = -1;
1946 
1947  dbname = mkdbname(fn, 1);
1948 
1949  if (!dbname) {
1950  goto out;
1951  }
1952 
1953  if ((fd = rz_sys_open(dbname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644)) == -1) {
1954  file_error(ms, errno, "cannot open `%s'", dbname);
1955  goto out;
1956  }
1957 
1958  if (write(fd, ar, sizeof(ar)) != (int)sizeof(ar)) {
1959  file_error(ms, errno, "error writing `%s'", dbname);
1960  goto beach;
1961  }
1962 
1963  if (lseek(fd, (off_t)sizeof(struct rz_magic), SEEK_SET) != sizeof(struct rz_magic)) {
1964  file_error(ms, errno, "error seeking `%s'", dbname);
1965  goto beach;
1966  }
1967 
1968  if (write(fd, *magicp, (sizeof(struct rz_magic) * *nmagicp)) != (int)(sizeof(struct rz_magic) * *nmagicp)) {
1969  file_error(ms, errno, "error writing `%s'", dbname);
1970  goto beach;
1971  }
1972 
1973  rv = 0;
1974 beach:
1975  (void)close(fd);
1976 out:
1977  free(dbname);
1978  return rv;
1979 }
static const ut32 ar[]
Definition: apprentice.c:1935
static char * mkdbname(const char *, int)
Definition: apprentice.c:1985
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define O_BINARY
Definition: cpipe.c:13
static static fork write
Definition: sflib.h:33
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep lseek
Definition: sflib.h:113
RZ_API int rz_sys_open(const char *path, int perm, int mode)
Definition: sys.c:1740
#define O_WRONLY
Definition: sftypes.h:487
#define O_CREAT
Definition: sftypes.h:489
int off_t
Definition: sftypes.h:41
#define O_TRUNC
Definition: sftypes.h:492
static const z80_opcode fd[]
Definition: z80_tab.h:997
#define SEEK_SET
Definition: zip.c:88

References ar, close, fd, file_error(), fn, free(), lseek, mkdbname(), O_BINARY, O_CREAT, O_TRUNC, O_WRONLY, out, rz_sys_open(), SEEK_SET, and write.

Referenced by apprentice_1().

◆ apprentice_load()

static int apprentice_load ( RzMagic *  ms,
struct rz_magic **  magicp,
ut32 nmagicp,
const char *  fn,
int  action 
)
static

Definition at line 593 of file apprentice.c.

593  {
594  ut32 marraycount, i, mentrycount = 0, starttest;
595  struct rz_magic_entry *marray;
596  struct stat st;
597  int errs = 0;
598 #if __WINDOWS__
599  HANDLE hdir;
600  WIN32_FIND_DATAW entry;
601  wchar_t dir[MAX_PATH];
602  wchar_t *wcpath;
603  char *cfname;
604  char subfn[1024];
605 #else
606  DIR *dir;
607  struct dirent *d;
608  char subfn[MAXPATHLEN];
609 #endif
610  ms->flags |= RZ_MAGIC_CHECK; /* Enable checks for parsed files */
611 
612  maxmagic = MAXMAGIS;
613  if (!(marray = calloc(maxmagic, sizeof(*marray)))) {
614  file_oomem(ms, maxmagic * sizeof(*marray));
615  return -1;
616  }
617  marraycount = 0;
618 
619  /* print silly verbose header for USG compat. */
620  if (action == FILE_CHECK) {
621  eprintf("%s\n", usg_hdr);
622  }
623 
624  /* load directory or file */
625  if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
626 #if __WINDOWS__ && !defined(__CYGWIN__)
627  if ((wcpath = rz_utf8_to_utf16(fn))) {
628  swprintf(dir, _countof(dir), L"%ls\\*.*", wcpath);
629  hdir = FindFirstFileW(dir, &entry);
630  if (!(hdir == INVALID_HANDLE_VALUE)) {
631  do {
632  if (wcsncmp(entry.cFileName, L".", 1) == 0)
633  continue;
634  if ((cfname = rz_utf16_to_utf8(entry.cFileName))) {
635  snprintf(subfn, sizeof(subfn), "%s/%s", fn, cfname);
636  if (stat(subfn, &st) == 0 && S_ISREG(st.st_mode)) {
637  load_1(ms, action, subfn, &errs, &marray, &marraycount);
638  }
639  free(cfname);
640  }
641  } while (FindNextFileW(hdir, &entry));
642  FindClose(hdir);
643  }
644  free(wcpath);
645  } else {
646  errs++;
647  }
648 #else
649  dir = opendir(fn);
650  if (dir) {
651  while ((d = readdir(dir))) {
652  if (*d->d_name == '.') {
653  continue;
654  }
655  snprintf(subfn, sizeof(subfn), "%s/%s", fn, d->d_name);
656  if (stat(subfn, &st) == 0 && S_ISREG(st.st_mode)) {
657  load_1(ms, action, subfn, &errs, &marray, &marraycount);
658  }
659  // else perror (subfn);
660  }
661  closedir(dir);
662  } else {
663  errs++;
664  }
665 #endif
666  } else {
667  load_1(ms, action, fn, &errs, &marray, &marraycount);
668  }
669  if (errs) {
670  goto out;
671  }
672 
673  /* Set types of tests */
674  for (i = 0; i < marraycount;) {
675  if (marray[i].mp->cont_level != 0) {
676  i++;
677  continue;
678  }
679 
680  starttest = i;
681  do {
682  set_test_type(marray[starttest].mp, marray[i].mp);
683  if (ms->flags & RZ_MAGIC_DEBUG) {
684  (void)fprintf(stderr, "%s%s%s: %s\n",
685  marray[i].mp->mimetype,
686  marray[i].mp->mimetype[0] == '\0' ? "" : "; ",
687  marray[i].mp->desc[0] ? marray[i].mp->desc : "(no description)",
688  marray[i].mp->flag & BINTEST ? "binary" : "text");
689  if (marray[i].mp->flag & BINTEST) {
690 #define SYMLEN 4 /* strlen("text") */
691  char *p = strstr(marray[i].mp->desc, "text");
692  if (p && (p == marray[i].mp->desc || isspace((unsigned char)p[-1])) &&
693  (p + SYMLEN - marray[i].mp->desc == MAXstring ||
694  (p[SYMLEN] == '\0' || isspace((unsigned char)p[SYMLEN])))) {
695  (void)fprintf(stderr,
696  "*** Possible binary test for text type\n");
697  }
698  }
699  }
700  } while (++i < marraycount && marray[i].mp->cont_level != 0);
701  }
702 
703  qsort(marray, marraycount, sizeof(*marray), apprentice_sort);
704 
705  /*
706  * Make sure that any level 0 "default" line is last (if one exists).
707  */
708  for (i = 0; i < marraycount; i++) {
709  if (marray[i].mp->cont_level == 0 &&
710  marray[i].mp->type == FILE_DEFAULT) {
711  while (++i < marraycount) {
712  if (marray[i].mp->cont_level == 0) {
713  break;
714  }
715  }
716  if (i != marraycount) {
717  ms->line = marray[i].mp->lineno; /* XXX - Ugh! */
718  file_magwarn(ms, "level 0 \"default\" did not sort last");
719  }
720  break;
721  }
722  }
723 
724  for (i = 0; i < marraycount; i++) {
725  mentrycount += marray[i].cont_count;
726  }
727 
728  if (!(*magicp = malloc(1 + (sizeof(**magicp) * mentrycount)))) {
729  file_oomem(ms, sizeof(**magicp) * mentrycount);
730  errs++;
731  goto out;
732  }
733 
734  mentrycount = 0;
735  for (i = 0; i < marraycount; i++) {
736  (void)memcpy(*magicp + mentrycount, marray[i].mp,
737  marray[i].cont_count * sizeof(**magicp));
738  mentrycount += marray[i].cont_count;
739  }
740 out:
741  for (i = 0; i < marraycount; i++) {
742  free(marray[i].mp);
743  }
744  free(marray);
745  if (errs) {
746  *magicp = NULL;
747  *nmagicp = 0;
748  return errs;
749  }
750  *nmagicp = mentrycount;
751  return 0;
752 }
lzma_index ** i
Definition: index.h:629
static int apprentice_sort(const void *, const void *)
Definition: apprentice.c:416
static void load_1(RzMagic *ms, int action, const char *file, int *errs, struct rz_magic_entry **marray, ut32 *marraycount)
Definition: apprentice.c:542
static const char usg_hdr[]
Definition: apprentice.c:105
static void set_test_type(struct rz_magic *mstart, struct rz_magic *m)
Definition: apprentice.c:430
static size_t maxmagic
Definition: apprentice.c:102
#define SYMLEN
#define S_ISDIR(mode)
Definition: compat.h:187
#define S_ISREG(mode)
Definition: compat.h:191
void file_magwarn(struct rz_magic_set *, const char *,...)
Definition: mdump.c:172
#define INVALID_HANDLE_VALUE
Definition: iowin32.c:21
snprintf
Definition: kernel.h:364
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static stat
Definition: sflib.h:131
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path static newfd static getpgrp static euid const sigset_t static mask const char static len const gid_t static list const char const char static newpath const char static library readdir
Definition: sflib.h:120
void qsort(void *a, size_t n, size_t es, int(*cmp)(const void *, const void *))
Definition: qsort.h:130
#define eprintf(x, y...)
Definition: rlcc.c:7
#define d(i)
Definition: sha256.c:44
Definition: sftypes.h:48
Definition: zipcmp.c:77
Definition: apprentice.c:69
ut32 cont_count
Definition: apprentice.c:71
struct rz_magic * mp
Definition: apprentice.c:70
Definition: sftypes.h:80
DWORD * HANDLE
#define L
Definition: zip_err_str.c:7

References test-lz4-speed::action, apprentice_sort(), calloc(), rz_magic_entry::cont_count, d, eprintf, file_magwarn(), file_oomem(), fn, free(), HANDLE, i, INVALID_HANDLE_VALUE, isspace, L, load_1(), malloc(), maxmagic, memcpy(), rz_magic_entry::mp, NULL, out, p, qsort(), readdir, S_ISDIR, S_ISREG, set_test_type(), snprintf, stat, SYMLEN, and usg_hdr.

Referenced by apprentice_1().

◆ apprentice_map()

static int apprentice_map ( RzMagic *  ms,
struct rz_magic **  magicp,
ut32 nmagicp,
const char *  fn 
)
static

Definition at line 1836 of file apprentice.c.

1836  {
1837  int fd;
1838  struct stat st;
1839  ut32 *ptr;
1840  ut32 version;
1841  int needsbyteswap;
1842  char *dbname = NULL;
1843  void *mm = NULL;
1844 
1845  dbname = mkdbname(fn, 0);
1846  if (!dbname) {
1847  goto error2;
1848  }
1849 
1850  if ((fd = rz_sys_open(dbname, O_RDONLY | O_BINARY, 0)) == -1) {
1851  goto error2;
1852  }
1853 
1854  if (fstat(fd, &st) == -1) {
1855  file_error(ms, errno, "cannot stat `%s'", dbname);
1856  goto error1;
1857  }
1858  if (st.st_size < 8) {
1859  file_error(ms, 0, "file `%s' is too small", dbname);
1860  goto error1;
1861  }
1862 
1863 #if QUICK
1864  if ((mm = mmap(0, (size_t)st.st_size, PROT_READ, // OPENBSDBUG |PROT_WRITE,
1865  MAP_PRIVATE | MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
1866  file_error(ms, errno, "cannot map `%s'", dbname);
1867  goto error1;
1868  }
1869 #define RET 2
1870 #else
1871  if (!(mm = malloc((size_t)st.st_size))) {
1872  file_oomem(ms, (size_t)st.st_size);
1873  goto error1;
1874  }
1875  if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) {
1876  file_badread(ms);
1877  goto error1;
1878  }
1879 #define RET 1
1880 #endif
1881  *magicp = mm;
1882  (void)close(fd);
1883  fd = -1;
1884  ptr = (ut32 *)(void *)*magicp;
1885 
1886  if (*ptr != MAGICNO) {
1887  if (swap4(*ptr) != MAGICNO) {
1888  // OPENBSDBUG file_error(ms, 0, "bad magic in `%s'");
1889  file_error(ms, 0, "bad magic in `%s'", dbname);
1890  goto error1;
1891  }
1892  needsbyteswap = 1;
1893  } else {
1894  needsbyteswap = 0;
1895  }
1896 
1897  version = needsbyteswap ? swap4(ptr[1]) : ptr[1];
1898  if (version != VERSIONNO) {
1899  file_error(ms, 0, "File %d.%d supports only %d version magic "
1900  "files. `%s' is version %d",
1902  VERSIONNO, dbname, version);
1903  goto error1;
1904  }
1905  *nmagicp = (ut32)(st.st_size / sizeof(struct rz_magic));
1906  if (*nmagicp > 0) {
1907  (*nmagicp)--;
1908  }
1909  (*magicp)++;
1910  if (needsbyteswap) {
1911  byteswap(*magicp, *nmagicp);
1912  }
1913  free(dbname);
1914  return RET;
1915 
1916 error1:
1917  if (fd != -1) {
1918  (void)close(fd);
1919  }
1920  if (mm) {
1921 #if QUICK
1922  (void)munmap((void *)mm, (size_t)st.st_size);
1923 #else
1924  free(mm);
1925 #endif
1926  } else {
1927  *magicp = NULL;
1928  *nmagicp = 0;
1929  }
1930 error2:
1931  free(dbname);
1932  return -1;
1933 }
static char * version
Definition: acr.h:4
#define MAP_FILE
Definition: apprentice.c:66
static void byteswap(struct rz_magic *, ut32)
Definition: apprentice.c:2011
static ut32 swap4(ut32)
Definition: apprentice.c:2033
#define RET
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset fstat
Definition: sflib.h:107
void file_badread(struct rz_magic_set *)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags mmap
Definition: sflib.h:115
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset munmap
Definition: sflib.h:43
#define FILE_VERSION_MAJOR
Definition: patchlevel.h:3
#define patchlevel
Definition: patchlevel.h:4
#define PROT_READ
Definition: sftypes.h:95
#define MAP_PRIVATE
Definition: sftypes.h:102
int size_t
Definition: sftypes.h:40
#define O_RDONLY
Definition: sftypes.h:486
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References byteswap(), close, fd, file_badread(), file_error(), file_oomem(), FILE_VERSION_MAJOR, fn, free(), fstat, malloc(), MAP_FILE, MAP_PRIVATE, mkdbname(), mmap, munmap, NULL, O_BINARY, O_RDONLY, patchlevel, PROT_READ, read(), RET, rz_sys_open(), swap4(), and version.

Referenced by apprentice_1().

◆ apprentice_r_magic_strength()

static size_t apprentice_r_magic_strength ( const struct rz_magic *  m)
static

Definition at line 325 of file apprentice.c.

325  {
326 #define MULT 10
327  size_t val = 2 * MULT; /* baseline strength */
328 
329  switch (m->type) {
330  case FILE_DEFAULT: /* make sure this sorts last */
331  return 0;
332  case FILE_BYTE:
333  val += 1 * MULT;
334  break;
335  case FILE_SHORT:
336  case FILE_LESHORT:
337  case FILE_BESHORT:
338  val += 2 * MULT;
339  break;
340  case FILE_LONG:
341  case FILE_LELONG:
342  case FILE_BELONG:
343  case FILE_MELONG:
344  val += 4 * MULT;
345  break;
346  case FILE_PSTRING:
347  case FILE_STRING:
348  val += m->vallen * MULT;
349  break;
350  case FILE_BESTRING16:
351  case FILE_LESTRING16:
352  val += m->vallen * MULT / 2;
353  break;
354  case FILE_SEARCH:
355  case FILE_REGEX:
356  val += m->vallen * RZ_MAX(MULT / m->vallen, 1);
357  break;
358  case FILE_DATE:
359  case FILE_LEDATE:
360  case FILE_BEDATE:
361  case FILE_MEDATE:
362  case FILE_LDATE:
363  case FILE_LELDATE:
364  case FILE_BELDATE:
365  case FILE_MELDATE:
366  case FILE_FLOAT:
367  case FILE_BEFLOAT:
368  case FILE_LEFLOAT:
369  val += 4 * MULT;
370  break;
371  case FILE_QUAD:
372  case FILE_BEQUAD:
373  case FILE_LEQUAD:
374  case FILE_QDATE:
375  case FILE_LEQDATE:
376  case FILE_BEQDATE:
377  case FILE_QLDATE:
378  case FILE_LEQLDATE:
379  case FILE_BEQLDATE:
380  case FILE_DOUBLE:
381  case FILE_BEDOUBLE:
382  case FILE_LEDOUBLE:
383  val += 8 * MULT;
384  break;
385  default:
386  eprintf("Bad type %d\n", m->type);
387  abort();
388  }
389 
390  switch (m->reln) {
391  case 'x': /* matches anything penalize */
392  case '!': /* matches almost anything penalize */
393  val = 0;
394  break;
395  case '=': /* Exact match, prefer */
396  val += MULT;
397  break;
398  case '>':
399  case '<': /* comparison match reduce strength */
400  val -= 2 * MULT;
401  break;
402  case '^':
403  case '&': /* masking bits, we could count them too */
404  val -= MULT;
405  break;
406  default:
407  eprintf("Bad relation %c\n", m->reln);
408  abort();
409  }
410  return val ? val : 1; /* ensure we only return 0 for FILE_DEFAULT */
411 }
#define MULT
ut16 val
Definition: armass64_const.h:6
#define RZ_MAX(x, y)

References eprintf, regress::m, MULT, RZ_MAX, and val.

Referenced by apprentice_sort().

◆ apprentice_sort()

static int apprentice_sort ( const void *  a,
const void *  b 
)
static

Definition at line 416 of file apprentice.c.

416  {
417  const struct rz_magic_entry *ma = a;
418  const struct rz_magic_entry *mb = b;
419  size_t sa = apprentice_r_magic_strength(ma->mp);
420  size_t sb = apprentice_r_magic_strength(mb->mp);
421  if (sa == sb) {
422  return 0;
423  }
424  if (sa > sb) {
425  return -1;
426  }
427  return 1;
428 }
static size_t apprentice_r_magic_strength(const struct rz_magic *)
Definition: apprentice.c:325
static SblHeader sb
Definition: bin_mbn.c:26
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41

References a, apprentice_r_magic_strength(), b, rz_magic_entry::mp, and sb.

Referenced by apprentice_load().

◆ bgets()

static const char* bgets ( char *  line,
size_t  line_sz,
const char *  data 
)
static

Definition at line 491 of file apprentice.c.

491  {
492  if (!*data) {
493  return NULL;
494  }
495  const char *nl = strchr(data, '\n');
496  const int nlsz = nl
497  ? nl - data + 1
498  : RZ_MIN(line_sz, strlen(data));
499  rz_str_ncpy(line, data, nlsz);
500  if (!data[nlsz]) {
501  return NULL;
502  }
503  return data + nlsz;
504 }
line
Definition: setup.py:34
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
Definition: str.c:923
#define RZ_MIN(x, y)

References setup::line, NULL, RZ_MIN, and rz_str_ncpy().

Referenced by load_b().

◆ bs1()

static void bs1 ( struct rz_magic *  m)
static

Definition at line 2076 of file apprentice.c.

2076  {
2077  m->cont_level = swap2(m->cont_level);
2078  m->offset = swap4((ut32)m->offset);
2079  m->in_offset = swap4((ut32)m->in_offset);
2080  m->lineno = swap4((ut32)m->lineno);
2081  if (MAGIC_IS_STRING(m->type)) {
2082  m->str_range = swap4(m->str_range);
2083  m->str_flags = swap4(m->str_flags);
2084  } else {
2085  m->value.q = swap8(m->value.q);
2086  m->num_mask = swap8(m->num_mask);
2087  }
2088 }
static ut16 swap2(ut16)
Definition: apprentice.c:2021
static ut64 swap8(ut64)
Definition: apprentice.c:2047

References regress::m, swap2(), swap4(), and swap8().

Referenced by byteswap().

◆ byteswap()

static void byteswap ( struct rz_magic *  magic,
ut32  nmagic 
)
static

Definition at line 2011 of file apprentice.c.

2011  {
2012  ut32 i;
2013  for (i = 0; i < nmagic; i++) {
2014  bs1(&magic[i]);
2015  }
2016 }
static void bs1(struct rz_magic *)
Definition: apprentice.c:2076

References bs1(), and i.

Referenced by apprentice_map().

◆ check_cond()

static int check_cond ( RzMagic *  ms,
int  cond,
ut32  cont_level 
)
static

Definition at line 914 of file apprentice.c.

914  {
915  int last_cond;
916  last_cond = ms->c.li[cont_level].last_cond;
917 
918  switch (cond) {
919  case COND_IF:
920  if (last_cond != COND_NONE && last_cond != COND_ELIF) {
921  if (ms->flags & RZ_MAGIC_CHECK) {
922  file_magwarn(ms, "syntax error: `if'");
923  }
924  return -1;
925  }
926  last_cond = COND_IF;
927  break;
928  case COND_ELIF:
929  if (last_cond != COND_IF && last_cond != COND_ELIF) {
930  if (ms->flags & RZ_MAGIC_CHECK) {
931  file_magwarn(ms, "syntax error: `elif'");
932  }
933  return -1;
934  }
935  last_cond = COND_ELIF;
936  break;
937  case COND_ELSE:
938  if (last_cond != COND_IF && last_cond != COND_ELIF) {
939  if (ms->flags & RZ_MAGIC_CHECK) {
940  file_magwarn(ms, "syntax error: `else'");
941  }
942  return -1;
943  }
944  last_cond = COND_NONE;
945  break;
946  case COND_NONE:
947  last_cond = COND_NONE;
948  break;
949  }
950 
951  ms->c.li[cont_level].last_cond = last_cond;
952  return 0;
953 }
#define cond(bop, top, mask, flags)

References cond, and file_magwarn().

Referenced by parse().

◆ check_format()

static int check_format ( RzMagic *  ms,
struct rz_magic *  m 
)
static

Definition at line 1515 of file apprentice.c.

1515  {
1516  char *ptr;
1517 
1518  for (ptr = m->desc; *ptr; ptr++) {
1519  if (*ptr == '%') {
1520  break;
1521  }
1522  }
1523  if (*ptr == '\0') {
1524  /* No format string; ok */
1525  return 1;
1526  }
1527 
1528  if (file_nformats != file_nnames) {
1529  return -1;
1530  }
1531 
1532  if (m->type >= file_nformats) {
1533  file_magwarn(ms, "Internal error inconsistency between "
1534  "m->type and format strings");
1535  return -1;
1536  }
1537  if (magic_file_formats[m->type] == FILE_FMT_NONE) {
1538  file_magwarn(ms, "No format string for `%s' with description "
1539  "`%s'",
1540  m->desc, magic_file_names[m->type]);
1541  return -1;
1542  }
1543 
1544  ptr++;
1545  if (ptr && check_format_type(ptr, magic_file_formats[m->type]) == -1) {
1546  /*
1547  * TODO: this error message is unhelpful if the format
1548  * string is not one character long
1549  */
1550  file_magwarn(ms, "Printf format `%c' is not valid for type "
1551  "`%s' in description `%s'",
1552  ptr && *ptr ? *ptr : '?',
1553  magic_file_names[m->type], m->desc);
1554  return -1;
1555  }
1556 
1557  for (; *ptr; ptr++) {
1558  if (*ptr == '%') {
1559  file_magwarn(ms,
1560  "Too many format strings (should have at most one) "
1561  "for `%s' with description `%s'",
1562  magic_file_names[m->type], m->desc);
1563  return -1;
1564  }
1565  }
1566  return 0;
1567 }
static const size_t file_nnames
Definition: apprentice.c:78
static const size_t file_nformats
Definition: apprentice.c:76
static int magic_file_formats[FILE_NAMES_SIZE]
Definition: apprentice.c:75
static const char * magic_file_names[FILE_NAMES_SIZE]
Definition: apprentice.c:77
static int check_format_type(const char *, int)
Definition: apprentice.c:1380

References check_format_type(), file_magwarn(), file_nformats, file_nnames, regress::m, magic_file_formats, and magic_file_names.

Referenced by parse().

◆ check_format_type()

static int check_format_type ( const char *  ptr,
int  type 
)
static

Definition at line 1380 of file apprentice.c.

1380  {
1381  int quad = 0;
1382  if (*ptr == '\0') {
1383  /* Missing format string; bad */
1384  return -1;
1385  }
1386 
1387  switch (type) {
1388  case FILE_FMT_QUAD:
1389  quad = 1;
1390  /*FALLTHROUGH*/
1391  case FILE_FMT_NUM:
1392  if (*ptr == '-') {
1393  ptr++;
1394  }
1395  if (*ptr == '.') {
1396  ptr++;
1397  }
1398  while (isdigit((ut8)*ptr)) {
1399  ptr++;
1400  }
1401  if (*ptr == '.') {
1402  ptr++;
1403  }
1404  while (isdigit((ut8)*ptr)) {
1405  ptr++;
1406  }
1407  if (quad) {
1408  if (*ptr++ != 'l') {
1409  return -1;
1410  }
1411  if (*ptr++ != 'l') {
1412  return -1;
1413  }
1414  }
1415  switch (*ptr++) {
1416  case 'l':
1417  switch (*ptr++) {
1418  case 'i':
1419  case 'd':
1420  case 'u':
1421  case 'x':
1422  case 'X':
1423  return 0;
1424  default:
1425  return -1;
1426  }
1427  case 'h':
1428  switch (*ptr++) {
1429  case 'h':
1430  switch (*ptr++) {
1431  case 'i':
1432  case 'd':
1433  case 'u':
1434  case 'x':
1435  case 'X':
1436  return 0;
1437  default:
1438  return -1;
1439  }
1440  case 'd':
1441  return 0;
1442  default:
1443  return -1;
1444  }
1445  case 'i':
1446  case 'c':
1447  case 'd':
1448  case 'u':
1449  case 'x':
1450  case 'X':
1451  return 0;
1452  default:
1453  return -1;
1454  }
1455  case FILE_FMT_FLOAT:
1456  case FILE_FMT_DOUBLE:
1457  if (*ptr == '-') {
1458  ptr++;
1459  }
1460  if (*ptr == '.') {
1461  ptr++;
1462  }
1463  while (isdigit((ut8)*ptr)) {
1464  ptr++;
1465  }
1466  if (*ptr == '.') {
1467  ptr++;
1468  }
1469  while (isdigit((ut8)*ptr)) {
1470  ptr++;
1471  }
1472 
1473  switch (*ptr++) {
1474  case 'e':
1475  case 'E':
1476  case 'f':
1477  case 'F':
1478  case 'g':
1479  case 'G':
1480  return 0;
1481 
1482  default:
1483  return -1;
1484  }
1485  case FILE_FMT_STR:
1486  if (*ptr == '-') {
1487  ptr++;
1488  }
1489  while (isdigit((ut8)*ptr)) {
1490  ptr++;
1491  }
1492  if (*ptr == '.') {
1493  ptr++;
1494  while (isdigit((ut8)*ptr)) {
1495  ptr++;
1496  }
1497  }
1498 
1499  if (*ptr++ == 's') {
1500  return 0;
1501  }
1502  return -1;
1503  default:
1504  /* internal error */
1505  abort();
1506  }
1507  /*NOTREACHED*/
1508  return -1;
1509 }
int type
Definition: mipsasm.c:17
#define isdigit(c)
Definition: safe-ctype.h:131

References isdigit, and type.

Referenced by check_format().

◆ eatsize()

static void eatsize ( const char **  p)
static

Definition at line 1811 of file apprentice.c.

1811  {
1812  const char *l = *p;
1813 
1814  if (LOWCASE(*l) == 'u') {
1815  l++;
1816  }
1817 
1818  switch (LOWCASE(*l)) {
1819  case 'l': /* long */
1820  case 's': /* short */
1821  case 'h': /* short */
1822  case 'b': /* char/byte */
1823  case 'c': /* char/byte */
1824  l++;
1825  /*FALLTHROUGH*/
1826  default:
1827  break;
1828  }
1829 
1830  *p = l;
1831 }
#define LOWCASE(l)
Definition: apprentice.c:63

References LOWCASE, and p.

Referenced by getvalue(), and parse().

◆ file_apprentice()

struct mlist* file_apprentice ( RzMagic *  ms,
const char *  fn,
int  action 
)

Definition at line 277 of file apprentice.c.

277  {
278  char *p, *mfn;
279  int file_err, errs = -1;
280  struct mlist *mlist;
281 
283  if (!fn) {
284  return NULL;
285  }
286 
287  if (!(mfn = strdup(fn))) {
288  file_oomem(ms, strlen(fn));
289  return NULL;
290  }
291  fn = mfn;
292 
293  if (!(mlist = malloc(sizeof(*mlist)))) {
294  free(mfn);
295  file_oomem(ms, sizeof(*mlist));
296  return NULL;
297  }
298  mlist->next = mlist->prev = mlist;
299 
300  while (fn) {
301  p = strchr(fn, PATHSEP);
302  if (p) {
303  *p++ = '\0';
304  }
305  if (*fn == '\0') {
306  break;
307  }
308  file_err = apprentice_1(ms, fn, action, mlist);
309  errs = RZ_MAX(errs, file_err);
310  fn = p;
311  }
312  if (errs == -1) {
313  free(mfn);
314  RZ_FREE(mlist);
315  file_error(ms, 0, "could not find any magic files!");
316  return NULL;
317  }
318  free(mfn);
319  return mlist;
320 }
static int apprentice_1(RzMagic *, const char *, int, struct mlist *)
Definition: apprentice.c:193
static void init_file_tables(void)
Definition: apprentice.c:174
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define RZ_FREE(x)
Definition: rz_types.h:369

References test-lz4-speed::action, apprentice_1(), file_error(), file_oomem(), fn, free(), init_file_tables(), malloc(), NULL, p, RZ_FREE, RZ_MAX, and strdup().

Referenced by rz_magic_check(), rz_magic_compile(), rz_magic_load(), and rz_magic_load_buffer().

◆ file_delmagic()

void file_delmagic ( struct rz_magic *  p,
int  type,
size_t  entries 
)

Definition at line 255 of file apprentice.c.

255  {
256  if (p) {
257  switch (type) {
258 #if QUICK
259  case 2:
260  p--;
261  (void)munmap((void *)p, sizeof(*p) * (entries + 1));
262  break;
263 #endif
264  case 1:
265  p--;
266  /*FALLTHROUGH*/
267  case 0:
268  RZ_FREE(p);
269  break;
270  default:
271  abort(); // do not abort, ever XXX this is a lib, so it shouldn just report an error
272  }
273  }
274 }
RzList * entries(RzBinFile *bf)
Definition: bin_ne.c:98

References entries(), munmap, p, RZ_FREE, and type.

Referenced by apprentice_1(), and free_mlist().

◆ file_showstr()

void file_showstr ( FILE *  fp,
const char *  s,
size_t  len 
)

Definition at line 1778 of file apprentice.c.

1778  {
1779  for (;;) {
1780  char c = *s++;
1781  if (len == ~0U) {
1782  if (c == '\0') {
1783  break;
1784  }
1785  } else {
1786  if (len-- == 0) {
1787  break;
1788  }
1789  }
1790  if (c >= 040 && c <= 0176) { /* TODO isprint && !iscntrl */
1791  fputc(c, fp);
1792  } else {
1793  fputc('\\', fp);
1794  switch (c) {
1795  case '\a': fputc('a', fp); break;
1796  case '\b': fputc('b', fp); break;
1797  case '\f': fputc('f', fp); break;
1798  case '\n': fputc('n', fp); break;
1799  case '\r': fputc('r', fp); break;
1800  case '\t': fputc('t', fp); break;
1801  case '\v': fputc('v', fp); break;
1802  default: fprintf(fp, "%.3o", c & 0377); break;
1803  }
1804  }
1805  }
1806 }
size_t len
Definition: 6502dis.c:15
static RzSocket * s
Definition: rtr.c:28
#define c(i)
Definition: sha256.c:43

References c, len, and s.

Referenced by file_mdump(), and mdebug().

◆ file_signextend()

ut64 file_signextend ( RzMagic *  ms,
struct rz_magic *  m,
ut64  v 
)

Definition at line 757 of file apprentice.c.

757  {
758  if (!(m->flag & UNSIGNED)) {
759  switch (m->type) {
760  /*
761  * Do not remove the casts below. They are
762  * vital. When later compared with the data,
763  * the sign extension must have happened.
764  */
765  case FILE_BYTE:
766  v = (char)v;
767  break;
768  case FILE_SHORT:
769  case FILE_BESHORT:
770  case FILE_LESHORT:
771  v = (short)v;
772  break;
773  case FILE_DATE:
774  case FILE_BEDATE:
775  case FILE_LEDATE:
776  case FILE_MEDATE:
777  case FILE_LDATE:
778  case FILE_BELDATE:
779  case FILE_LELDATE:
780  case FILE_MELDATE:
781  case FILE_LONG:
782  case FILE_BELONG:
783  case FILE_LELONG:
784  case FILE_MELONG:
785  case FILE_FLOAT:
786  case FILE_BEFLOAT:
787  case FILE_LEFLOAT:
788  v = (int32_t)v;
789  break;
790  case FILE_QUAD:
791  case FILE_BEQUAD:
792  case FILE_LEQUAD:
793  case FILE_QDATE:
794  case FILE_QLDATE:
795  case FILE_BEQDATE:
796  case FILE_BEQLDATE:
797  case FILE_LEQDATE:
798  case FILE_LEQLDATE:
799  case FILE_DOUBLE:
800  case FILE_BEDOUBLE:
801  case FILE_LEDOUBLE:
802  v = (int64_t)v;
803  break;
804  case FILE_STRING:
805  case FILE_PSTRING:
806  case FILE_BESTRING16:
807  case FILE_LESTRING16:
808  case FILE_REGEX:
809  case FILE_SEARCH:
810  case FILE_DEFAULT:
811  break;
812  default:
813  if (ms->flags & RZ_MAGIC_CHECK) {
814  file_magwarn(ms, "cannot happen: m->type=%d\n",
815  m->type);
816  }
817  return ~0U;
818  }
819  }
820  return v;
821 }
const char * v
Definition: dsignal.c:12
#define UNSIGNED(n, x)
long int64_t
Definition: sftypes.h:32
int int32_t
Definition: sftypes.h:33

References file_magwarn(), regress::m, UNSIGNED, and v.

Referenced by getvalue(), magiccheck(), mprint(), and parse().

◆ get_cond()

static int get_cond ( const char *  l,
const char **  t 
)
static

Definition at line 889 of file apprentice.c.

889  {
890  const struct cond_tbl_s *p;
891  static const struct cond_tbl_s {
892  char name[8];
893  size_t len;
894  int cond;
895  } cond_tbl[] = {
896  { "if", 2, COND_IF },
897  { "elif", 4, COND_ELIF },
898  { "else", 4, COND_ELSE },
899  { "", 0, COND_NONE },
900  };
901 
902  for (p = cond_tbl; p->len; p++) {
903  if (strncmp(l, p->name, p->len) == 0 &&
904  isspace((ut8)l[p->len])) {
905  if (t) {
906  *t = l + p->len;
907  }
908  break;
909  }
910  }
911  return p->cond;
912 }
Definition: z80asm.h:102

References cond, isspace, len, and p.

Referenced by parse().

◆ get_op()

static int get_op ( char  c)
static

Definition at line 875 of file apprentice.c.

875  {
876  switch (c) {
877  case '&': return FILE_OPAND;
878  case '|': return FILE_OPOR;
879  case '^': return FILE_OPXOR;
880  case '+': return FILE_OPADD;
881  case '-': return FILE_OPMINUS;
882  case '*': return FILE_OPMULTIPLY;
883  case '/': return FILE_OPDIVIDE;
884  case '%': return FILE_OPMODULO;
885  default: return -1;
886  }
887 }

References c.

Referenced by parse().

◆ get_type()

static int get_type ( const char *  l,
const char **  t 
)
static

Definition at line 160 of file apprentice.c.

160  {
161  const struct type_tbl_s *p;
162 
163  for (p = type_tbl; p->len; p++) {
164  if (strncmp(l, p->name, p->len) == 0) {
165  if (t) {
166  *t = l + p->len;
167  }
168  break;
169  }
170  }
171  return p->type;
172 }
static const struct type_tbl_s type_tbl[]

References p, and type_tbl.

Referenced by parse().

◆ getstr()

static const char * getstr ( RzMagic *  ms,
const char *  s,
char *  p,
int  plen,
int slen,
int  action 
)
static

Definition at line 1637 of file apprentice.c.

1637  {
1638  const char *origs = s;
1639  char *origp = p;
1640  char *pmax = p + plen - 1;
1641  int c, val;
1642 
1643  while ((c = *s++) != '\0') {
1644  if (isspace((ut8)c)) {
1645  break;
1646  }
1647  if (p >= pmax) {
1648  file_error(ms, 0, "string too long: `%s'", origs);
1649  return NULL;
1650  }
1651  if (c == '\\') {
1652  switch ((c = *s++)) {
1653  case '\0':
1654  if (action == FILE_COMPILE) {
1655  file_magwarn(ms, "incomplete escape");
1656  }
1657  goto out;
1658  case '\t':
1659  if (action == FILE_COMPILE) {
1660  file_magwarn(ms,
1661  "escaped tab found, use \\t instead");
1662  action++;
1663  }
1664  /*FALLTHROUGH*/
1665  default:
1666  if (action == FILE_COMPILE) {
1667  if (isprint((ut8)c)) {
1668  file_magwarn(ms,
1669  "no need to escape `%c'", c);
1670  } else {
1671  file_magwarn(ms,
1672  "unknown escape sequence: \\%03o", c);
1673  }
1674  }
1675  /*FALLTHROUGH*/
1676  /* space, perhaps force people to use \040? */
1677  case ' ':
1678 #if 0
1679  /*
1680  * Other things people escape, but shouldn't need to,
1681  * so we disallow them
1682  */
1683  case '\'':
1684  case '"':
1685  case '?':
1686 #endif
1687  /* Relations */
1688  case '>':
1689  case '<':
1690  case '&':
1691  case '^':
1692  case '=':
1693  case '!':
1694  /* and baskslash itself */
1695  case '\\':
1696  *p++ = (char)c;
1697  break;
1698  case 'a': *p++ = '\a'; break;
1699  case 'b': *p++ = '\b'; break;
1700  case 'f': *p++ = '\f'; break;
1701  case 'n': *p++ = '\n'; break;
1702  case 'r': *p++ = '\r'; break;
1703  case 't': *p++ = '\t'; break;
1704  case 'v': *p++ = '\v'; break;
1705  /* \ and up to 3 octal digits */
1706  case '0':
1707  case '1':
1708  case '2':
1709  case '3':
1710  case '4':
1711  case '5':
1712  case '6':
1713  case '7':
1714  val = c - '0';
1715  c = *s++; /* try for 2 */
1716  if (c >= '0' && c <= '7') {
1717  val = (val << 3) | (c - '0');
1718  c = *s++; /* try for 3 */
1719  if (c >= '0' && c <= '7') {
1720  val = (val << 3) | (c - '0');
1721  } else {
1722  --s;
1723  }
1724  } else {
1725  --s;
1726  }
1727  *p++ = (char)val;
1728  break;
1729 
1730  /* \x and up to 2 hex digits */
1731  case 'x':
1732  val = 'x'; /* Default if no digits */
1733  c = hextoint(*s++); /* Get next char */
1734  if (c >= 0) {
1735  val = c;
1736  c = hextoint(*s++);
1737  if (c >= 0) {
1738  val = (val << 4) + c;
1739  } else {
1740  --s;
1741  }
1742  } else {
1743  --s;
1744  }
1745  *p++ = (char)val;
1746  break;
1747  }
1748  } else {
1749  *p++ = (char)c;
1750  }
1751  }
1752 out:
1753  *p = '\0';
1754  *slen = p - origp;
1755  return s;
1756 }
static int hextoint(int)
Definition: apprentice.c:1759
#define isprint(c)
Definition: safe-ctype.h:137

References test-lz4-speed::action, c, file_error(), file_magwarn(), hextoint(), isprint, isspace, NULL, out, p, s, and val.

Referenced by getvalue().

◆ getvalue()

static int getvalue ( RzMagic *  ms,
struct rz_magic *  m,
const char **  p,
int  action 
)
static

Definition at line 1574 of file apprentice.c.

1574  {
1575  int slen;
1576 
1577  switch (m->type) {
1578  case FILE_BESTRING16:
1579  case FILE_LESTRING16:
1580  case FILE_STRING:
1581  case FILE_PSTRING:
1582  case FILE_REGEX:
1583  case FILE_SEARCH:
1584  *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen, action);
1585  if (!*p) {
1586  if (ms->flags & RZ_MAGIC_CHECK) {
1587  file_magwarn(ms, "cannot get string from `%s'",
1588  m->value.s);
1589  }
1590  return -1;
1591  }
1592  m->vallen = slen;
1593  if (m->type == FILE_PSTRING) {
1594  m->vallen++;
1595  }
1596  return 0;
1597  case FILE_FLOAT:
1598  case FILE_BEFLOAT:
1599  case FILE_LEFLOAT:
1600  if (m->reln != 'x') {
1601  char *ep;
1602 #ifdef HAVE_STRTOF
1603  m->value.f = strtof(*p, &ep);
1604 #else
1605  m->value.f = (float)strtod(*p, &ep);
1606 #endif
1607  *p = ep;
1608  }
1609  return 0;
1610  case FILE_DOUBLE:
1611  case FILE_BEDOUBLE:
1612  case FILE_LEDOUBLE:
1613  if (m->reln != 'x') {
1614  char *ep;
1615  m->value.d = strtod(*p, &ep);
1616  *p = ep;
1617  }
1618  return 0;
1619  default:
1620  if (m->reln != 'x') {
1621  char *ep;
1622  m->value.q = file_signextend(ms, m,
1623  (ut64)strtoull(*p, &ep, 0));
1624  *p = ep;
1625  eatsize(p);
1626  }
1627  return 0;
1628  }
1629 }
ut64 file_signextend(RzMagic *ms, struct rz_magic *m, ut64 v)
Definition: apprentice.c:757
static void eatsize(const char **)
Definition: apprentice.c:1811
static const char * getstr(RzMagic *, const char *, char *, int, int *, int)
Definition: apprentice.c:1637
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References test-lz4-speed::action, eatsize(), file_magwarn(), file_signextend(), test-lz4-speed::float, getstr(), regress::m, p, and ut64().

Referenced by parse().

◆ hextoint()

static int hextoint ( int  c)
static

Definition at line 1759 of file apprentice.c.

1759  {
1760  if (!isascii((ut8)c)) {
1761  return -1;
1762  }
1763  if (isdigit((ut8)c)) {
1764  return c - '0';
1765  }
1766  if ((c >= 'a') && (c <= 'f')) {
1767  return c + 10 - 'a';
1768  }
1769  if ((c >= 'A') && (c <= 'F')) {
1770  return c + 10 - 'A';
1771  }
1772  return -1;
1773 }

References c, and isdigit.

Referenced by getstr().

◆ init_file_tables()

static void init_file_tables ( void  )
static

Definition at line 174 of file apprentice.c.

174  {
175  static bool done = false;
176  const struct type_tbl_s *p;
177  if (done) {
178  return;
179  }
180  done = true;
181  for (p = type_tbl; p->len; p++) {
182  if (p->type >= FILE_NAMES_SIZE) {
183  continue;
184  }
185  magic_file_names[p->type] = p->name;
186  magic_file_formats[p->type] = p->format;
187  }
188 }
struct tab * done
Definition: enough.c:233

References done, magic_file_formats, magic_file_names, p, and type_tbl.

Referenced by file_apprentice().

◆ load_1()

static void load_1 ( RzMagic *  ms,
int  action,
const char *  file,
int errs,
struct rz_magic_entry **  marray,
ut32 marraycount 
)
static

Definition at line 542 of file apprentice.c.

542  {
543  if (*file == '#') {
544  load_b(ms, action, file, errs, marray, marraycount);
545  return;
546  }
547  char line[BUFSIZ];
548  size_t lineno = 0;
549  FILE *f = rz_sys_fopen(ms->file = file, "r");
550  if (!f) {
551  if (errno != ENOENT) {
552  file_error(ms, errno, "cannot read magic file `%s'", file);
553  }
554  (*errs)++;
555  return;
556  }
557  /* read and parse this file */
558  for (ms->line = 1; fgets(line, sizeof(line), f) != NULL; ms->line++) {
559  size_t len = strlen(line);
560  if (len == 0) { /* null line, garbage, etc */
561  continue;
562  }
563  if (line[len - 1] == '\n') {
564  lineno++;
565  line[len - 1] = '\0'; /* delete newline */
566  }
567  if (line[0] == '\0') { /* empty, do not parse */
568  continue;
569  }
570  if (line[0] == '#') { /* comment, do not parse */
571  continue;
572  }
573  if (len > mime_marker_len &&
574  memcmp(line, mime_marker, mime_marker_len) == 0) {
575  /* MIME type */
576  if (parse_mime(ms, marray, marraycount,
577  line + mime_marker_len) != 0) {
578  (*errs)++;
579  }
580  continue;
581  }
582  if (parse(ms, marray, marraycount, line, lineno, action) != 0) {
583  (*errs)++;
584  }
585  }
586  fclose(f);
587 }
static const char mime_marker[]
Definition: apprentice.c:106
static void load_b(RzMagic *ms, int action, const char *data, int *errs, struct rz_magic_entry **marray, ut32 *marraycount)
Definition: apprentice.c:506
static int parse(RzMagic *, struct rz_magic_entry **, ut32 *, const char *, size_t, int)
Definition: apprentice.c:958
static int parse_mime(RzMagic *, struct rz_magic_entry **, ut32 *, const char *)
Definition: apprentice.c:1341
static const size_t mime_marker_len
Definition: apprentice.c:107
string FILE
Definition: benchmark.py:21
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
#define ENOENT
Definition: sftypes.h:112
#define f(i)
Definition: sha256.c:46
Definition: gzappend.c:170

References test-lz4-speed::action, ENOENT, f, benchmark::FILE, file_error(), len, setup::line, load_b(), mime_marker, mime_marker_len, NULL, parse(), parse_mime(), and rz_sys_fopen().

Referenced by apprentice_load().

◆ load_b()

static void load_b ( RzMagic *  ms,
int  action,
const char *  data,
int errs,
struct rz_magic_entry **  marray,
ut32 marraycount 
)
static

Definition at line 506 of file apprentice.c.

506  {
507  char line[BUFSIZ];
508  size_t lineno = 0;
509  /* read and parse this file */
510  for (ms->line = 1; (data = bgets(line, sizeof(line), data)) != NULL; ms->line++) {
511  size_t len = strlen(line);
512  if (len == 0) { /* null line, garbage, etc */
513  continue;
514  }
515  if (line[len - 1] == '\n') {
516  lineno++;
517  line[len - 1] = '\0'; /* delete newline */
518  }
519  if (line[0] == '\0') { /* empty, do not parse */
520  continue;
521  }
522  if (line[0] == '#') { /* comment, do not parse */
523  continue;
524  }
525  if (len > mime_marker_len && !memcmp(line, mime_marker, mime_marker_len)) {
526  /* MIME type */
527  if (parse_mime(ms, marray, marraycount,
528  line + mime_marker_len) != 0) {
529  (*errs)++;
530  }
531  continue;
532  }
533  if (parse(ms, marray, marraycount, line, lineno, action) != 0) {
534  (*errs)++;
535  }
536  }
537 }
static const char * bgets(char *line, size_t line_sz, const char *data)
Definition: apprentice.c:491

References test-lz4-speed::action, bgets(), len, setup::line, mime_marker, mime_marker_len, NULL, parse(), and parse_mime().

Referenced by load_1().

◆ mkdbname()

static char * mkdbname ( const char *  fn,
int  strip 
)
static

Definition at line 1985 of file apprentice.c.

1985  {
1986  char *buf = NULL;
1987  int fnlen, extlen;
1988  if (strip) {
1989  const char *p;
1990  if ((p = strrchr(fn, '/')) != NULL) {
1991  fn = ++p;
1992  }
1993  }
1994  fnlen = strlen(fn);
1995  extlen = strlen(ext);
1996  if (fnlen + extlen + 1 > MAXPATHLEN) {
1997  return NULL;
1998  }
1999  buf = malloc(fnlen + extlen + 1);
2000  if (buf) {
2001  memcpy(buf, fn, fnlen);
2002  memcpy(buf + fnlen, ext, extlen);
2003  buf[fnlen + extlen] = 0;
2004  }
2005  return buf;
2006 }
static const char ext[]
Definition: apprentice.c:1981
voidpf void * buf
Definition: ioapi.h:138

References ext, fn, malloc(), memcpy(), NULL, p, and cmd_descs_generate::strip().

Referenced by apprentice_compile(), and apprentice_map().

◆ parse()

static int parse ( RzMagic *  ms,
struct rz_magic_entry **  mentryp,
ut32 nmentryp,
const char *  line,
size_t  lineno,
int  action 
)
static

Definition at line 958 of file apprentice.c.

958  {
959  static ut32 last_cont_level = 0;
960  size_t i;
961  struct rz_magic_entry *me;
962  struct rz_magic *m;
963  const char *l = line;
964  char *t;
965  int op;
966  ut32 cont_level = 0;
967 
968  for (; *l == '>'; l++, cont_level++) {
969  ;
970  }
971  if (cont_level == 0 || cont_level > last_cont_level) {
972  if (file_check_mem(ms, cont_level) == -1) {
973  return -1;
974  }
975  }
976  last_cont_level = cont_level;
977 #define ALLOC_CHUNK (size_t)10
978 #define ALLOC_INCR (size_t)200
979  if (cont_level != 0) {
980  if (*nmentryp == 0) {
981  file_error(ms, 0, "No current entry for continuation");
982  return -1;
983  }
984  me = &(*mentryp)[*nmentryp - 1];
985  if (me->cont_count == me->max_count) {
986  struct rz_magic *nm;
987  size_t cnt = me->max_count + ALLOC_CHUNK;
988  if (!(nm = realloc(me->mp, sizeof(*nm) * cnt))) {
989  file_oomem(ms, sizeof(*nm) * cnt);
990  return -1;
991  }
992  me->mp = nm;
993  me->max_count = cnt;
994  }
995  m = &me->mp[me->cont_count++];
996  (void)memset(m, 0, sizeof(*m));
997  m->cont_level = cont_level;
998  } else {
999  if (*nmentryp == maxmagic) {
1000  struct rz_magic_entry *mp;
1001 
1002  maxmagic += ALLOC_INCR;
1003  if (!(mp = realloc(*mentryp, sizeof(*mp) * maxmagic))) {
1004  file_oomem(ms, sizeof(*mp) * maxmagic);
1005  return -1;
1006  }
1007  (void)memset(&mp[*nmentryp], 0, sizeof(*mp) * ALLOC_INCR);
1008  *mentryp = mp;
1009  }
1010  me = &(*mentryp)[*nmentryp];
1011  if (!me->mp) {
1012  if (!(m = malloc(sizeof(*m) * ALLOC_CHUNK))) {
1013  file_oomem(ms, sizeof(*m) * ALLOC_CHUNK);
1014  return -1;
1015  }
1016  me->mp = m;
1017  me->max_count = ALLOC_CHUNK;
1018  } else {
1019  m = me->mp;
1020  }
1021  (void)memset(m, 0, sizeof(*m));
1022  m->cont_level = 0;
1023  me->cont_count = 1;
1024  }
1025  m->lineno = lineno;
1026 
1027  if (*l == '&') { /* m->cont_level == 0 checked below. */
1028  ++l; /* step over */
1029  m->flag |= OFFADD;
1030  }
1031  if (*l == '(') {
1032  ++l; /* step over */
1033  m->flag |= INDIR;
1034  if (m->flag & OFFADD) {
1035  m->flag = (m->flag & ~OFFADD) | INDIROFFADD;
1036  }
1037 
1038  if (*l == '&') { /* m->cont_level == 0 checked below */
1039  ++l; /* step over */
1040  m->flag |= OFFADD;
1041  }
1042  }
1043  /* Indirect offsets are not valid at level 0. */
1044  if (m->cont_level == 0 && (m->flag & (OFFADD | INDIROFFADD))) {
1045  if (ms->flags & RZ_MAGIC_CHECK) {
1046  file_magwarn(ms, "relative offset at level 0");
1047  }
1048  }
1049 
1050  /* get offset, then skip over it */
1051  m->offset = (ut32)strtoul(l, &t, 0);
1052  if ((l == t) && (ms->flags & RZ_MAGIC_CHECK)) {
1053  file_magwarn(ms, "offset `%s' invalid", l);
1054  }
1055  l = t;
1056 
1057  if (m->flag & INDIR) {
1058  m->in_type = FILE_LONG;
1059  m->in_offset = 0;
1060  /*
1061  * read [.lbs][+-]nnnnn)
1062  */
1063  if (*l == '.') {
1064  l++;
1065  switch (*l) {
1066  case 'l':
1067  m->in_type = FILE_LELONG;
1068  break;
1069  case 'L':
1070  m->in_type = FILE_BELONG;
1071  break;
1072  case 'm':
1073  m->in_type = FILE_MELONG;
1074  break;
1075  case 'h':
1076  case 's':
1077  m->in_type = FILE_LESHORT;
1078  break;
1079  case 'H':
1080  case 'S':
1081  m->in_type = FILE_BESHORT;
1082  break;
1083  case 'c':
1084  case 'b':
1085  case 'C':
1086  case 'B':
1087  m->in_type = FILE_BYTE;
1088  break;
1089  case 'e':
1090  case 'f':
1091  case 'g':
1092  m->in_type = FILE_LEDOUBLE;
1093  break;
1094  case 'E':
1095  case 'F':
1096  case 'G':
1097  m->in_type = FILE_BEDOUBLE;
1098  break;
1099  default:
1100  if (ms->flags & RZ_MAGIC_CHECK) {
1101  file_magwarn(ms,
1102  "indirect offset type `%c' invalid",
1103  *l);
1104  }
1105  break;
1106  }
1107  l++;
1108  }
1109 
1110  m->in_op = 0;
1111  if (*l == '~') {
1112  m->in_op |= FILE_OPINVERSE;
1113  l++;
1114  }
1115  if ((op = get_op(*l)) != -1) {
1116  m->in_op |= op;
1117  l++;
1118  }
1119  if (*l == '(') {
1120  m->in_op |= FILE_OPINDIRECT;
1121  l++;
1122  }
1123  if (isdigit((ut8)*l) || *l == '-') {
1124  m->in_offset = (int32_t)strtol(l, &t, 0);
1125  if (l == t) {
1126  if (ms->flags & RZ_MAGIC_CHECK) {
1127  file_magwarn(ms,
1128  "in_offset `%s' invalid", l);
1129  }
1130  }
1131  l = t;
1132  }
1133  if (*l++ != ')' ||
1134  ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
1135  if (ms->flags & RZ_MAGIC_CHECK) {
1136  file_magwarn(ms,
1137  "missing ')' in indirect offset");
1138  }
1139  }
1140  }
1141  EATAB;
1142 
1143  m->cond = get_cond(l, &l);
1144  if (check_cond(ms, m->cond, cont_level) == -1) {
1145  return -1;
1146  }
1147  EATAB;
1148 
1149  if (*l == 'u') {
1150  ++l;
1151  m->flag |= UNSIGNED;
1152  }
1153 
1154  m->type = get_type(l, &l);
1155  if (m->type == FILE_INVALID) {
1156  if (ms->flags & RZ_MAGIC_CHECK) {
1157  file_magwarn(ms, "type `%s' invalid", l);
1158  }
1159  return -1;
1160  }
1161 
1162  /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
1163  /* New and improved: ~ & | ^ + - * / % -- exciting, isn't it? */
1164 
1165  m->mask_op = 0;
1166  if (*l == '~') {
1167  if (!MAGIC_IS_STRING(m->type)) {
1168  m->mask_op |= FILE_OPINVERSE;
1169  } else if (ms->flags & RZ_MAGIC_CHECK) {
1170  file_magwarn(ms, "'~' invalid for string types");
1171  }
1172  ++l;
1173  }
1174  m->str_range = 0;
1175  m->str_flags = 0;
1176  m->num_mask = 0;
1177  if ((op = get_op(*l)) != -1) {
1178  if (!MAGIC_IS_STRING(m->type)) {
1179  ut64 val;
1180  ++l;
1181  m->mask_op |= op;
1182  val = (ut64)strtoull(l, &t, 0);
1183  l = t;
1184  m->num_mask = file_signextend(ms, m, val);
1185  eatsize(&l);
1186  } else if (op == FILE_OPDIVIDE) {
1187  int have_range = 0;
1188  while (!isspace((ut8) * ++l)) {
1189  switch (*l) {
1190  case '0':
1191  case '1':
1192  case '2':
1193  case '3':
1194  case '4':
1195  case '5':
1196  case '6':
1197  case '7':
1198  case '8':
1199  case '9':
1200  if (have_range &&
1201  (ms->flags & RZ_MAGIC_CHECK)) {
1202  file_magwarn(ms,
1203  "multiple ranges");
1204  }
1205  have_range = 1;
1206  m->str_range = strtoul(l, &t, 0);
1207  if (m->str_range == 0) {
1208  file_magwarn(ms,
1209  "zero range");
1210  }
1211  l = t - 1;
1212  break;
1213  case CHAR_COMPACT_BLANK:
1214  m->str_flags |= STRING_COMPACT_BLANK;
1215  break;
1216  case CHAR_COMPACT_OPTIONAL_BLANK:
1217  m->str_flags |=
1218  STRING_COMPACT_OPTIONAL_BLANK;
1219  break;
1220  case CHAR_IGNORE_LOWERCASE:
1221  m->str_flags |= STRING_IGNORE_LOWERCASE;
1222  break;
1223  case CHAR_IGNORE_UPPERCASE:
1224  m->str_flags |= STRING_IGNORE_UPPERCASE;
1225  break;
1226  case CHAR_REGEX_OFFSET_START:
1227  m->str_flags |= REGEX_OFFSET_START;
1228  break;
1229  default:
1230  if (ms->flags & RZ_MAGIC_CHECK) {
1231  file_magwarn(ms,
1232  "string extension `%c' invalid",
1233  *l);
1234  }
1235  return -1;
1236  }
1237  /* allow multiple '/' for readability */
1238  if (l[1] == '/' && !isspace((ut8)l[2])) {
1239  l++;
1240  }
1241  }
1242  if (string_modifier_check(ms, m) == -1) {
1243  return -1;
1244  }
1245  } else {
1246  if (ms->flags & RZ_MAGIC_CHECK) {
1247  file_magwarn(ms, "invalid string op: %c", *t);
1248  }
1249  return -1;
1250  }
1251  }
1252  /*
1253  * We used to set mask to all 1's here, instead let's just not do
1254  * anything if mask = 0 (unless you have a better idea)
1255  */
1256  EATAB;
1257 
1258  switch (*l) {
1259  case '>':
1260  case '<':
1261  /* Old-style anding: "0 byte &0x80 dynamically linked" */
1262  case '&':
1263  case '^':
1264  case '=':
1265  m->reln = *l;
1266  ++l;
1267  if (*l == '=') {
1268  /* HP compat: ignore &= etc. */
1269  ++l;
1270  }
1271  break;
1272  case '!':
1273  m->reln = *l;
1274  ++l;
1275  break;
1276  default:
1277  m->reln = '='; /* the default relation */
1278  if (*l == 'x' && ((isascii((ut8)l[1]) && isspace((ut8)l[1])) || !l[1])) {
1279  m->reln = *l;
1280  ++l;
1281  }
1282  break;
1283  }
1284  /*
1285  * Grab the value part, except for an 'x' reln.
1286  */
1287  if (m->reln != 'x' && getvalue(ms, m, &l, action)) {
1288  return -1;
1289  }
1290 
1291  /*
1292  * TODO finish this macro and start using it!
1293  * #define offsetcheck {if (offset > HOWMANY-1)
1294  * magwarn("offset too big"); }
1295  */
1296 
1297  /*
1298  * Now get last part - the description
1299  */
1300  EATAB;
1301  if (l[0] == '\b') {
1302  ++l;
1303  m->flag |= NOSPACE;
1304  } else if ((l[0] == '\\') && (l[1] == 'b')) {
1305  ++l;
1306  ++l;
1307  m->flag |= NOSPACE;
1308  }
1309  for (i = 0; (m->desc[i++] = *l++) != '\0' && i < sizeof(m->desc);) {
1310  }
1311  if (i == sizeof(m->desc)) {
1312  m->desc[sizeof(m->desc) - 1] = '\0';
1313  if (ms->flags & RZ_MAGIC_CHECK) {
1314  file_magwarn(ms, "description `%s' truncated", m->desc);
1315  }
1316  }
1317 
1318  /*
1319  * We only do this check while compiling, or if any of the magic
1320  * files were not compiled.
1321  */
1322  if (ms->flags & RZ_MAGIC_CHECK) {
1323  if (check_format(ms, m) == -1) {
1324  return -1;
1325  }
1326  }
1327  if (action == FILE_CHECK) {
1328  file_mdump(m);
1329  }
1330  m->mimetype[0] = '\0'; /* initialise MIME type to none */
1331  if (m->cont_level == 0) {
1332  ++(*nmentryp); /* make room for next */
1333  }
1334  return 0;
1335 }
ut8 op
Definition: 6502dis.c:13
static int check_format(RzMagic *, struct rz_magic *)
Definition: apprentice.c:1515
static int check_cond(RzMagic *ms, int cond, ut32 cont_level)
Definition: apprentice.c:914
#define EATAB
Definition: apprentice.c:57
#define ALLOC_INCR
static int get_cond(const char *l, const char **t)
Definition: apprentice.c:889
static int get_type(const char *l, const char **t)
Definition: apprentice.c:160
static int getvalue(RzMagic *ms, struct rz_magic *, const char **, int)
Definition: apprentice.c:1574
static int string_modifier_check(RzMagic *ms, struct rz_magic *m)
Definition: apprentice.c:823
static int get_op(char)
Definition: apprentice.c:875
#define ALLOC_CHUNK
void file_mdump(struct rz_magic *)
Definition: mdump.c:47
int file_check_mem(struct rz_magic_set *, unsigned int)
return memset(p, 0, total)
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
ut32 max_count
Definition: apprentice.c:72
Definition: dis.c:32

References test-lz4-speed::action, ALLOC_CHUNK, ALLOC_INCR, check_cond(), check_format(), rz_magic_entry::cont_count, EATAB, eatsize(), file_check_mem(), file_error(), file_magwarn(), file_mdump(), file_oomem(), file_signextend(), get_cond(), get_op(), get_type(), getvalue(), i, isdigit, isspace, setup::line, regress::m, malloc(), rz_magic_entry::max_count, maxmagic, memset(), rz_magic_entry::mp, op, realloc(), string_modifier_check(), UNSIGNED, ut64(), and val.

Referenced by load_1(), and load_b().

◆ parse_mime()

static int parse_mime ( RzMagic *  ms,
struct rz_magic_entry **  mentryp,
ut32 nmentryp,
const char *  line 
)
static

Definition at line 1341 of file apprentice.c.

1341  {
1342  size_t i;
1343  const char *l = line;
1344  struct rz_magic *m;
1345  struct rz_magic_entry *me;
1346 
1347  if (*nmentryp == 0) {
1348  file_error(ms, 0, "No current entry for MIME type");
1349  return -1;
1350  }
1351 
1352  me = &(*mentryp)[*nmentryp - 1];
1353  m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1];
1354 
1355  if (m->mimetype[0] != '\0') {
1356  file_error(ms, 0, "Current entry already has a MIME type: %s\n"
1357  "Description: %s\nNew type: %s",
1358  m->mimetype, m->desc, l);
1359  return -1;
1360  }
1361 
1362  EATAB;
1363  for (i = 0;
1364  *l && ((isascii((ut8)*l) && isalnum((ut8)*l)) || strchr("-+/.", *l)) && i < sizeof(m->mimetype);
1365  m->mimetype[i++] = *l++) {
1366  }
1367  if (i == sizeof(m->mimetype)) {
1368  m->desc[sizeof(m->mimetype) - 1] = '\0';
1369  if (ms->flags & RZ_MAGIC_CHECK) {
1370  file_magwarn(ms, "MIME type `%s' truncated %zu",
1371  m->mimetype, i);
1372  }
1373  } else {
1374  m->mimetype[i] = '\0';
1375  }
1376 
1377  return (i > 0) ? 0 : -1;
1378 }
#define isalnum(c)
Definition: safe-ctype.h:127

References rz_magic_entry::cont_count, EATAB, file_error(), file_magwarn(), i, isalnum, setup::line, regress::m, and rz_magic_entry::mp.

Referenced by load_1(), and load_b().

◆ set_test_type()

static void set_test_type ( struct rz_magic *  mstart,
struct rz_magic *  m 
)
static

Definition at line 430 of file apprentice.c.

430  {
431  switch (m->type) {
432  case FILE_BYTE:
433  case FILE_SHORT:
434  case FILE_LONG:
435  case FILE_DATE:
436  case FILE_BESHORT:
437  case FILE_BELONG:
438  case FILE_BEDATE:
439  case FILE_LESHORT:
440  case FILE_LELONG:
441  case FILE_LEDATE:
442  case FILE_LDATE:
443  case FILE_BELDATE:
444  case FILE_LELDATE:
445  case FILE_MEDATE:
446  case FILE_MELDATE:
447  case FILE_MELONG:
448  case FILE_QUAD:
449  case FILE_LEQUAD:
450  case FILE_BEQUAD:
451  case FILE_QDATE:
452  case FILE_LEQDATE:
453  case FILE_BEQDATE:
454  case FILE_QLDATE:
455  case FILE_LEQLDATE:
456  case FILE_BEQLDATE:
457  case FILE_FLOAT:
458  case FILE_BEFLOAT:
459  case FILE_LEFLOAT:
460  case FILE_DOUBLE:
461  case FILE_BEDOUBLE:
462  case FILE_LEDOUBLE:
463  case FILE_STRING:
464  case FILE_PSTRING:
465  case FILE_BESTRING16:
466  case FILE_LESTRING16:
467  /* binary test, set flag */
468  mstart->flag |= BINTEST;
469  break;
470  case FILE_REGEX:
471  case FILE_SEARCH:
472  /* binary test if pattern is not text */
473  if (file_looks_utf8((const ut8 *)m->value.s, m->vallen, NULL, NULL) == 0) {
474  mstart->flag |= BINTEST;
475  }
476  break;
477  case FILE_DEFAULT:
478  /* can't deduce anything; we shouldn't see this at the
479  top level anyway */
480  break;
481  case FILE_INVALID:
482  default:
483  /* invalid search type, but no need to complain here */
484  break;
485  }
486 }
int file_looks_utf8(const ut8 *, size_t, unichar *, size_t *)
Definition: ascmagic.c:605

References file_looks_utf8(), regress::m, and NULL.

Referenced by apprentice_load().

◆ string_modifier_check()

static int string_modifier_check ( RzMagic *  ms,
struct rz_magic *  m 
)
static

Definition at line 823 of file apprentice.c.

823  {
824  if ((ms->flags & RZ_MAGIC_CHECK) == 0) {
825  return 0;
826  }
827 
828  switch (m->type) {
829  case FILE_BESTRING16:
830  case FILE_LESTRING16:
831  if (m->str_flags != 0) {
832  file_magwarn(ms,
833  "no modifiers allowed for 16-bit strings\n");
834  return -1;
835  }
836  break;
837  case FILE_STRING:
838  case FILE_PSTRING:
839  if ((m->str_flags & REGEX_OFFSET_START) != 0) {
840  file_magwarn(ms,
841  "'/%c' only allowed on regex and search\n",
842  CHAR_REGEX_OFFSET_START);
843  return -1;
844  }
845  break;
846  case FILE_SEARCH:
847  if (m->str_range == 0) {
848  file_magwarn(ms,
849  "missing range; defaulting to %d\n",
850  STRING_DEFAULT_RANGE);
851  m->str_range = STRING_DEFAULT_RANGE;
852  return -1;
853  }
854  break;
855  case FILE_REGEX:
856  if ((m->str_flags & STRING_COMPACT_BLANK) != 0) {
857  file_magwarn(ms, "'/%c' not allowed on regex\n",
858  CHAR_COMPACT_BLANK);
859  return -1;
860  }
861  if ((m->str_flags & STRING_COMPACT_OPTIONAL_BLANK) != 0) {
862  file_magwarn(ms, "'/%c' not allowed on regex\n",
863  CHAR_COMPACT_OPTIONAL_BLANK);
864  return -1;
865  }
866  break;
867  default:
868  file_magwarn(ms, "coding error: m->type=%d\n",
869  m->type);
870  return -1;
871  }
872  return 0;
873 }

References file_magwarn(), and regress::m.

Referenced by parse().

◆ swap2()

static ut16 swap2 ( ut16  sv)
static

Definition at line 2021 of file apprentice.c.

2021  {
2022  ut16 rv;
2023  ut8 *s = (ut8 *)(void *)&sv;
2024  ut8 *d = (ut8 *)(void *)&rv;
2025  d[0] = s[1];
2026  d[1] = s[0];
2027  return rv;
2028 }
uint16_t ut16

References d, and s.

Referenced by bs1().

◆ swap4()

static ut32 swap4 ( ut32  sv)
static

Definition at line 2033 of file apprentice.c.

2033  {
2034  ut32 rv;
2035  ut8 *s = (ut8 *)(void *)&sv;
2036  ut8 *d = (ut8 *)(void *)&rv;
2037  d[0] = s[3];
2038  d[1] = s[2];
2039  d[2] = s[1];
2040  d[3] = s[0];
2041  return rv;
2042 }

References d, and s.

Referenced by apprentice_map(), and bs1().

◆ swap8()

static ut64 swap8 ( ut64  sv)
static

Definition at line 2047 of file apprentice.c.

2047  {
2048  ut64 rv;
2049  ut8 *s = (ut8 *)(void *)&sv;
2050  ut8 *d = (ut8 *)(void *)&rv;
2051 #if 0
2052  d[0] = s[3];
2053  d[1] = s[2];
2054  d[2] = s[1];
2055  d[3] = s[0];
2056  d[4] = s[7];
2057  d[5] = s[6];
2058  d[6] = s[5];
2059  d[7] = s[4];
2060 #else
2061  d[0] = s[7];
2062  d[1] = s[6];
2063  d[2] = s[5];
2064  d[3] = s[4];
2065  d[4] = s[3];
2066  d[5] = s[2];
2067  d[6] = s[1];
2068  d[7] = s[0];
2069 #endif
2070  return rv;
2071 }

References d, s, and ut64().

Referenced by bs1().

Variable Documentation

◆ ar

const ut32 ar[]
static
Initial value:
= {
MAGICNO, VERSIONNO
}

Definition at line 1935 of file apprentice.c.

Referenced by apprentice_compile(), jemalloc_get_bins(), jemalloc_get_chunks(), jemalloc_print_narenas(), reloc_cmp(), and reloc_target_cmp().

◆ ext

◆ file_nformats

const size_t file_nformats = FILE_NAMES_SIZE
static

Definition at line 76 of file apprentice.c.

Referenced by check_format().

◆ file_nnames

const size_t file_nnames = FILE_NAMES_SIZE
static

Definition at line 78 of file apprentice.c.

Referenced by check_format(), and file_mdump().

◆ magic_file_formats

int magic_file_formats[FILE_NAMES_SIZE]
static

Definition at line 75 of file apprentice.c.

Referenced by check_format(), and init_file_tables().

◆ magic_file_names

const char* magic_file_names[FILE_NAMES_SIZE]
static

Definition at line 77 of file apprentice.c.

Referenced by check_format(), file_mdump(), and init_file_tables().

◆ magicsize

size_t magicsize = sizeof(struct rz_magic)
static

Definition at line 103 of file apprentice.c.

Referenced by apprentice_1().

◆ maxmagic

size_t maxmagic = 0
static

Definition at line 102 of file apprentice.c.

Referenced by apprentice_load(), and parse().

◆ mime_marker

const char mime_marker[] = "!:mime"
static

Definition at line 106 of file apprentice.c.

Referenced by load_1(), and load_b().

◆ mime_marker_len

const size_t mime_marker_len = sizeof(mime_marker) - 1
static

Definition at line 107 of file apprentice.c.

Referenced by load_1(), and load_b().

◆ type_tbl

const struct type_tbl_s type_tbl[]
static

Referenced by get_type(), and init_file_tables().

◆ usg_hdr

const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"
static

Definition at line 105 of file apprentice.c.

Referenced by apprentice_load().