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

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

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

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

27 */
28/*
29 * apprentice - make one pass through /etc/magic, learning its secrets.
30 */
31
32#include "file.h"
33
34#ifndef lint
35FILE_RCSID("@(#)$File: apprentice.c,v 1.147 2009/02/03 20:27:51 christos Exp $")
35FILE_RCSID("@(#)$File: apprentice.c,v 1.151 2009/03/18 15:19:23 christos Exp $")
36#endif /* lint */
37
38#include "magic.h"
39#include "patchlevel.h"
40#include <stdlib.h>
41#ifdef HAVE_UNISTD_H
42#include <unistd.h>
43#endif

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

84
85int file_formats[FILE_NAMES_SIZE];
86const size_t file_nformats = FILE_NAMES_SIZE;
87const char *file_names[FILE_NAMES_SIZE];
88const size_t file_nnames = FILE_NAMES_SIZE;
89
90private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
91private int hextoint(int);
36#endif /* lint */
37
38#include "magic.h"
39#include "patchlevel.h"
40#include <stdlib.h>
41#ifdef HAVE_UNISTD_H
42#include <unistd.h>
43#endif

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

84
85int file_formats[FILE_NAMES_SIZE];
86const size_t file_nformats = FILE_NAMES_SIZE;
87const char *file_names[FILE_NAMES_SIZE];
88const size_t file_nnames = FILE_NAMES_SIZE;
89
90private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
91private int hextoint(int);
92private const char *getstr(struct magic_set *, const char *, char *, int,
93 int *, int);
92private const char *getstr(struct magic_set *, struct magic *, const char *,
93 int);
94private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
95 const char *, size_t, int);
96private void eatsize(const char **);
97private int apprentice_1(struct magic_set *, const char *, int, struct mlist *);
98private size_t apprentice_magic_strength(const struct magic *);
99private int apprentice_sort(const void *, const void *);
100private int apprentice_load(struct magic_set *, struct magic **, uint32_t *,
101 const char *, int);

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

319}
320
321protected void
322file_delmagic(struct magic *p, int type, size_t entries)
323{
324 if (p == NULL)
325 return;
326 switch (type) {
94private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
95 const char *, size_t, int);
96private void eatsize(const char **);
97private int apprentice_1(struct magic_set *, const char *, int, struct mlist *);
98private size_t apprentice_magic_strength(const struct magic *);
99private int apprentice_sort(const void *, const void *);
100private int apprentice_load(struct magic_set *, struct magic **, uint32_t *,
101 const char *, int);

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

319}
320
321protected void
322file_delmagic(struct magic *p, int type, size_t entries)
323{
324 if (p == NULL)
325 return;
326 switch (type) {
327#ifdef QUICK
328 case 2:
327 case 2:
328#ifdef QUICK
329 p--;
330 (void)munmap((void *)p, sizeof(*p) * (entries + 1));
331 break;
329 p--;
330 (void)munmap((void *)p, sizeof(*p) * (entries + 1));
331 break;
332#else
333 (void)&entries;
334 abort();
335 /*NOTREACHED*/
332#endif
333 case 1:
334 p--;
335 /*FALLTHROUGH*/
336 case 0:
337 free(p);
338 break;
339 default:

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

1709
1710 ptr++;
1711 if (check_format_type(ptr, file_formats[m->type]) == -1) {
1712 /*
1713 * TODO: this error message is unhelpful if the format
1714 * string is not one character long
1715 */
1716 file_magwarn(ms, "Printf format `%c' is not valid for type "
336#endif
337 case 1:
338 p--;
339 /*FALLTHROUGH*/
340 case 0:
341 free(p);
342 break;
343 default:

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

1713
1714 ptr++;
1715 if (check_format_type(ptr, file_formats[m->type]) == -1) {
1716 /*
1717 * TODO: this error message is unhelpful if the format
1718 * string is not one character long
1719 */
1720 file_magwarn(ms, "Printf format `%c' is not valid for type "
1717 "`%s' in description `%s'",
1718 ptr && *ptr ? *ptr : '?',
1721 "`%s' in description `%s'", *ptr ? *ptr : '?',
1719 file_names[m->type], m->desc);
1720 return -1;
1721 }
1722
1723 for (; *ptr; ptr++) {
1724 if (*ptr == '%') {
1725 file_magwarn(ms,
1726 "Too many format strings (should have at most one) "

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

1735/*
1736 * Read a numeric value from a pointer, into the value union of a magic
1737 * pointer, according to the magic type. Update the string pointer to point
1738 * just after the number read. Return 0 for success, non-zero for failure.
1739 */
1740private int
1741getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
1742{
1722 file_names[m->type], m->desc);
1723 return -1;
1724 }
1725
1726 for (; *ptr; ptr++) {
1727 if (*ptr == '%') {
1728 file_magwarn(ms,
1729 "Too many format strings (should have at most one) "

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

1738/*
1739 * Read a numeric value from a pointer, into the value union of a magic
1740 * pointer, according to the magic type. Update the string pointer to point
1741 * just after the number read. Return 0 for success, non-zero for failure.
1742 */
1743private int
1744getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
1745{
1743 int slen;
1744
1745 switch (m->type) {
1746 case FILE_BESTRING16:
1747 case FILE_LESTRING16:
1748 case FILE_STRING:
1749 case FILE_PSTRING:
1750 case FILE_REGEX:
1751 case FILE_SEARCH:
1746 switch (m->type) {
1747 case FILE_BESTRING16:
1748 case FILE_LESTRING16:
1749 case FILE_STRING:
1750 case FILE_PSTRING:
1751 case FILE_REGEX:
1752 case FILE_SEARCH:
1752 *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen, action);
1753 *p = getstr(ms, m, *p, action == FILE_COMPILE);
1753 if (*p == NULL) {
1754 if (ms->flags & MAGIC_CHECK)
1755 file_magwarn(ms, "cannot get string from `%s'",
1756 m->value.s);
1757 return -1;
1758 }
1754 if (*p == NULL) {
1755 if (ms->flags & MAGIC_CHECK)
1756 file_magwarn(ms, "cannot get string from `%s'",
1757 m->value.s);
1758 return -1;
1759 }
1759 m->vallen = slen;
1760 if (m->type == FILE_PSTRING)
1761 m->vallen++;
1762 return 0;
1763 case FILE_FLOAT:
1764 case FILE_BEFLOAT:
1765 case FILE_LEFLOAT:
1766 if (m->reln != 'x') {
1767 char *ep;
1768#ifdef HAVE_STRTOF
1769 m->value.f = strtof(*p, &ep);

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

1792 }
1793 return 0;
1794 }
1795}
1796
1797/*
1798 * Convert a string containing C character escapes. Stop at an unescaped
1799 * space or tab.
1760 return 0;
1761 case FILE_FLOAT:
1762 case FILE_BEFLOAT:
1763 case FILE_LEFLOAT:
1764 if (m->reln != 'x') {
1765 char *ep;
1766#ifdef HAVE_STRTOF
1767 m->value.f = strtof(*p, &ep);

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

1790 }
1791 return 0;
1792 }
1793}
1794
1795/*
1796 * Convert a string containing C character escapes. Stop at an unescaped
1797 * space or tab.
1800 * Copy the converted version to "p", returning its length in *slen.
1801 * Return updated scan pointer as function result.
1798 * Copy the converted version to "m->value.s", and the length in m->vallen.
1799 * Return updated scan pointer as function result. Warn if set.
1802 */
1803private const char *
1800 */
1801private const char *
1804getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int action)
1802getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
1805{
1806 const char *origs = s;
1803{
1804 const char *origs = s;
1805 char *p = m->value.s;
1806 size_t plen = sizeof(m->value.s);
1807 char *origp = p;
1808 char *pmax = p + plen - 1;
1809 int c;
1810 int val;
1811
1812 while ((c = *s++) != '\0') {
1813 if (isspace((unsigned char) c))
1814 break;
1815 if (p >= pmax) {
1816 file_error(ms, 0, "string too long: `%s'", origs);
1817 return NULL;
1818 }
1819 if (c == '\\') {
1820 switch(c = *s++) {
1821
1822 case '\0':
1807 char *origp = p;
1808 char *pmax = p + plen - 1;
1809 int c;
1810 int val;
1811
1812 while ((c = *s++) != '\0') {
1813 if (isspace((unsigned char) c))
1814 break;
1815 if (p >= pmax) {
1816 file_error(ms, 0, "string too long: `%s'", origs);
1817 return NULL;
1818 }
1819 if (c == '\\') {
1820 switch(c = *s++) {
1821
1822 case '\0':
1823 if (action == FILE_COMPILE)
1823 if (warn)
1824 file_magwarn(ms, "incomplete escape");
1825 goto out;
1826
1827 case '\t':
1824 file_magwarn(ms, "incomplete escape");
1825 goto out;
1826
1827 case '\t':
1828 if (action == FILE_COMPILE) {
1828 if (warn) {
1829 file_magwarn(ms,
1830 "escaped tab found, use \\t instead");
1829 file_magwarn(ms,
1830 "escaped tab found, use \\t instead");
1831 action++;
1831 warn = 0; /* already did */
1832 }
1833 /*FALLTHROUGH*/
1834 default:
1832 }
1833 /*FALLTHROUGH*/
1834 default:
1835 if (action == FILE_COMPILE) {
1836 if (isprint((unsigned char)c))
1837 file_magwarn(ms,
1838 "no need to escape `%c'", c);
1839 else
1840 file_magwarn(ms,
1841 "unknown escape sequence: \\%03o", c);
1835 if (warn) {
1836 if (isprint((unsigned char)c)) {
1837 /* Allow escaping of
1838 * ``relations'' */
1839 if (strchr("<>&^=!", c)
1840 == NULL) {
1841 file_magwarn(ms, "no "
1842 "need to escape "
1843 "`%c'", c);
1844 }
1845 } else {
1846 file_magwarn(ms,
1847 "unknown escape sequence: "
1848 "\\%03o", c);
1849 }
1842 }
1843 /*FALLTHROUGH*/
1844 /* space, perhaps force people to use \040? */
1845 case ' ':
1846#if 0
1847 /*
1848 * Other things people escape, but shouldn't need to,
1849 * so we disallow them

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

1932 *p++ = (char)val;
1933 break;
1934 }
1935 } else
1936 *p++ = (char)c;
1937 }
1938out:
1939 *p = '\0';
1850 }
1851 /*FALLTHROUGH*/
1852 /* space, perhaps force people to use \040? */
1853 case ' ':
1854#if 0
1855 /*
1856 * Other things people escape, but shouldn't need to,
1857 * so we disallow them

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

1940 *p++ = (char)val;
1941 break;
1942 }
1943 } else
1944 *p++ = (char)c;
1945 }
1946out:
1947 *p = '\0';
1940 *slen = p - origp;
1948 m->vallen = p - origp;
1949 if (m->type == FILE_PSTRING)
1950 m->vallen++;
1941 return s;
1942}
1943
1944
1945/* Single hex char to int; -1 if not a hex char. */
1946private int
1947hextoint(int c)
1948{

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

2081 goto error1;
2082 }
2083#define RET 2
2084#else
2085 if ((mm = CAST(void *, malloc((size_t)st.st_size))) == NULL) {
2086 file_oomem(ms, (size_t)st.st_size);
2087 goto error1;
2088 }
1951 return s;
1952}
1953
1954
1955/* Single hex char to int; -1 if not a hex char. */
1956private int
1957hextoint(int c)
1958{

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

2091 goto error1;
2092 }
2093#define RET 2
2094#else
2095 if ((mm = CAST(void *, malloc((size_t)st.st_size))) == NULL) {
2096 file_oomem(ms, (size_t)st.st_size);
2097 goto error1;
2098 }
2089 if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) {
2099 if (read(fd, mm, (size_t)st.st_size) != (ssize_t)st.st_size) {
2090 file_badread(ms);
2091 goto error1;
2092 }
2093#define RET 1
2094#endif
2095 *magicp = CAST(struct magic *, mm);
2096 (void)close(fd);
2097 fd = -1;

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

2104 needsbyteswap = 1;
2105 } else
2106 needsbyteswap = 0;
2107 if (needsbyteswap)
2108 version = swap4(ptr[1]);
2109 else
2110 version = ptr[1];
2111 if (version != VERSIONNO) {
2100 file_badread(ms);
2101 goto error1;
2102 }
2103#define RET 1
2104#endif
2105 *magicp = CAST(struct magic *, mm);
2106 (void)close(fd);
2107 fd = -1;

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

2114 needsbyteswap = 1;
2115 } else
2116 needsbyteswap = 0;
2117 if (needsbyteswap)
2118 version = swap4(ptr[1]);
2119 else
2120 version = ptr[1];
2121 if (version != VERSIONNO) {
2112 file_error(ms, 0, "File %d.%d supports only %d version magic "
2122 file_error(ms, 0, "File %d.%d supports only version %d magic "
2113 "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
2114 VERSIONNO, dbname, version);
2115 goto error1;
2116 }
2117 *nmagicp = (uint32_t)(st.st_size / sizeof(struct magic));
2118 if (*nmagicp > 0)
2119 (*nmagicp)--;
2120 (*magicp)++;

--- 207 unchanged lines hidden ---
2123 "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
2124 VERSIONNO, dbname, version);
2125 goto error1;
2126 }
2127 *nmagicp = (uint32_t)(st.st_size / sizeof(struct magic));
2128 if (*nmagicp > 0)
2129 (*nmagicp)--;
2130 (*magicp)++;

--- 207 unchanged lines hidden ---