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 --- |