apprentice.c (276415) | apprentice.c (277592) |
---|---|
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.227 2014/11/28 02:46:39 christos Exp $") | 35FILE_RCSID("@(#)$File: apprentice.c,v 1.229 2015/01/01 17:07:34 christos Exp $") |
36#endif /* lint */ 37 38#include "magic.h" 39#include <stdlib.h> 40#ifdef HAVE_UNISTD_H 41#include <unistd.h> 42#endif 43#ifdef HAVE_STDDEF_H --- 479 unchanged lines hidden (view full) --- 523 for (i = 0; i < MAGIC_SETS; i++) 524 ms->mlist[i] = NULL; 525 ms->file = "unknown"; 526 ms->line = 0; 527 ms->indir_max = FILE_INDIR_MAX; 528 ms->name_max = FILE_NAME_MAX; 529 ms->elf_shnum_max = FILE_ELF_SHNUM_MAX; 530 ms->elf_phnum_max = FILE_ELF_PHNUM_MAX; | 36#endif /* lint */ 37 38#include "magic.h" 39#include <stdlib.h> 40#ifdef HAVE_UNISTD_H 41#include <unistd.h> 42#endif 43#ifdef HAVE_STDDEF_H --- 479 unchanged lines hidden (view full) --- 523 for (i = 0; i < MAGIC_SETS; i++) 524 ms->mlist[i] = NULL; 525 ms->file = "unknown"; 526 ms->line = 0; 527 ms->indir_max = FILE_INDIR_MAX; 528 ms->name_max = FILE_NAME_MAX; 529 ms->elf_shnum_max = FILE_ELF_SHNUM_MAX; 530 ms->elf_phnum_max = FILE_ELF_PHNUM_MAX; |
531 ms->elf_notes_max = FILE_ELF_NOTES_MAX; |
|
531 return ms; 532free: 533 free(ms); 534 return NULL; 535} 536 537private void 538apprentice_unmap(struct magic_map *map) --- 1060 unchanged lines hidden (view full) --- 1599 break; 1600 } 1601 1602 ms->c.li[cont_level].last_cond = last_cond; 1603 return 0; 1604} 1605#endif /* ENABLE_CONDITIONALS */ 1606 | 532 return ms; 533free: 534 free(ms); 535 return NULL; 536} 537 538private void 539apprentice_unmap(struct magic_map *map) --- 1060 unchanged lines hidden (view full) --- 1600 break; 1601 } 1602 1603 ms->c.li[cont_level].last_cond = last_cond; 1604 return 0; 1605} 1606#endif /* ENABLE_CONDITIONALS */ 1607 |
1608private int 1609parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp) 1610{ 1611 const char *l = *lp; 1612 1613 while (!isspace((unsigned char)*++l)) 1614 switch (*l) { 1615 case CHAR_INDIRECT_RELATIVE: 1616 m->str_flags |= INDIRECT_RELATIVE; 1617 break; 1618 default: 1619 if (ms->flags & MAGIC_CHECK) 1620 file_magwarn(ms, "indirect modifier `%c' " 1621 "invalid", *l); 1622 *lp = l; 1623 return -1; 1624 } 1625 *lp = l; 1626 return 0; 1627} 1628 1629private void 1630parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp, 1631 int op) 1632{ 1633 const char *l = *lp; 1634 char *t; 1635 uint64_t val; 1636 1637 ++l; 1638 m->mask_op |= op; 1639 val = (uint64_t)strtoull(l, &t, 0); 1640 l = t; 1641 m->num_mask = file_signextend(ms, m, val); 1642 eatsize(&l); 1643 *lp = l; 1644} 1645 1646private int 1647parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp) 1648{ 1649 const char *l = *lp; 1650 char *t; 1651 int have_range = 0; 1652 1653 while (!isspace((unsigned char)*++l)) { 1654 switch (*l) { 1655 case '0': case '1': case '2': 1656 case '3': case '4': case '5': 1657 case '6': case '7': case '8': 1658 case '9': 1659 if (have_range && (ms->flags & MAGIC_CHECK)) 1660 file_magwarn(ms, "multiple ranges"); 1661 have_range = 1; 1662 m->str_range = CAST(uint32_t, strtoul(l, &t, 0)); 1663 if (m->str_range == 0) 1664 file_magwarn(ms, "zero range"); 1665 l = t - 1; 1666 break; 1667 case CHAR_COMPACT_WHITESPACE: 1668 m->str_flags |= STRING_COMPACT_WHITESPACE; 1669 break; 1670 case CHAR_COMPACT_OPTIONAL_WHITESPACE: 1671 m->str_flags |= STRING_COMPACT_OPTIONAL_WHITESPACE; 1672 break; 1673 case CHAR_IGNORE_LOWERCASE: 1674 m->str_flags |= STRING_IGNORE_LOWERCASE; 1675 break; 1676 case CHAR_IGNORE_UPPERCASE: 1677 m->str_flags |= STRING_IGNORE_UPPERCASE; 1678 break; 1679 case CHAR_REGEX_OFFSET_START: 1680 m->str_flags |= REGEX_OFFSET_START; 1681 break; 1682 case CHAR_BINTEST: 1683 m->str_flags |= STRING_BINTEST; 1684 break; 1685 case CHAR_TEXTTEST: 1686 m->str_flags |= STRING_TEXTTEST; 1687 break; 1688 case CHAR_TRIM: 1689 m->str_flags |= STRING_TRIM; 1690 break; 1691 case CHAR_PSTRING_1_LE: 1692#define SET_LENGTH(a) m->str_flags = (m->str_flags & ~PSTRING_LEN) | (a) 1693 if (m->type != FILE_PSTRING) 1694 goto bad; 1695 SET_LENGTH(PSTRING_1_LE); 1696 break; 1697 case CHAR_PSTRING_2_BE: 1698 if (m->type != FILE_PSTRING) 1699 goto bad; 1700 SET_LENGTH(PSTRING_2_BE); 1701 break; 1702 case CHAR_PSTRING_2_LE: 1703 if (m->type != FILE_PSTRING) 1704 goto bad; 1705 SET_LENGTH(PSTRING_2_LE); 1706 break; 1707 case CHAR_PSTRING_4_BE: 1708 if (m->type != FILE_PSTRING) 1709 goto bad; 1710 SET_LENGTH(PSTRING_4_BE); 1711 break; 1712 case CHAR_PSTRING_4_LE: 1713 switch (m->type) { 1714 case FILE_PSTRING: 1715 case FILE_REGEX: 1716 break; 1717 default: 1718 goto bad; 1719 } 1720 SET_LENGTH(PSTRING_4_LE); 1721 break; 1722 case CHAR_PSTRING_LENGTH_INCLUDES_ITSELF: 1723 if (m->type != FILE_PSTRING) 1724 goto bad; 1725 m->str_flags |= PSTRING_LENGTH_INCLUDES_ITSELF; 1726 break; 1727 default: 1728 bad: 1729 if (ms->flags & MAGIC_CHECK) 1730 file_magwarn(ms, "string modifier `%c' " 1731 "invalid", *l); 1732 goto out; 1733 } 1734 /* allow multiple '/' for readability */ 1735 if (l[1] == '/' && !isspace((unsigned char)l[2])) 1736 l++; 1737 } 1738 if (string_modifier_check(ms, m) == -1) 1739 goto out; 1740 *lp = l; 1741 return 0; 1742out: 1743 *lp = l; 1744 return -1; 1745} 1746 |
|
1607/* 1608 * parse one line from magic file, put into magic[index++] if valid 1609 */ 1610private int 1611parse(struct magic_set *ms, struct magic_entry *me, const char *line, 1612 size_t lineno, int action) 1613{ 1614#ifdef ENABLE_CONDITIONALS --- 253 unchanged lines hidden (view full) --- 1868 m->mask_op |= FILE_OPINVERSE; 1869 else if (ms->flags & MAGIC_CHECK) 1870 file_magwarn(ms, "'~' invalid for string types"); 1871 ++l; 1872 } 1873 m->str_range = 0; 1874 m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0; 1875 if ((op = get_op(*l)) != -1) { | 1747/* 1748 * parse one line from magic file, put into magic[index++] if valid 1749 */ 1750private int 1751parse(struct magic_set *ms, struct magic_entry *me, const char *line, 1752 size_t lineno, int action) 1753{ 1754#ifdef ENABLE_CONDITIONALS --- 253 unchanged lines hidden (view full) --- 2008 m->mask_op |= FILE_OPINVERSE; 2009 else if (ms->flags & MAGIC_CHECK) 2010 file_magwarn(ms, "'~' invalid for string types"); 2011 ++l; 2012 } 2013 m->str_range = 0; 2014 m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0; 2015 if ((op = get_op(*l)) != -1) { |
1876 if (!IS_STRING(m->type)) { 1877 uint64_t val; 1878 ++l; 1879 m->mask_op |= op; 1880 val = (uint64_t)strtoull(l, &t, 0); 1881 l = t; 1882 m->num_mask = file_signextend(ms, m, val); 1883 eatsize(&l); 1884 } 1885 else if (op == FILE_OPDIVIDE) { 1886 int have_range = 0; 1887 while (!isspace((unsigned char)*++l)) { 1888 switch (*l) { 1889 case '0': case '1': case '2': 1890 case '3': case '4': case '5': 1891 case '6': case '7': case '8': 1892 case '9': 1893 if (have_range && 1894 (ms->flags & MAGIC_CHECK)) 1895 file_magwarn(ms, 1896 "multiple ranges"); 1897 have_range = 1; 1898 m->str_range = CAST(uint32_t, 1899 strtoul(l, &t, 0)); 1900 if (m->str_range == 0) 1901 file_magwarn(ms, 1902 "zero range"); 1903 l = t - 1; 1904 break; 1905 case CHAR_COMPACT_WHITESPACE: 1906 m->str_flags |= 1907 STRING_COMPACT_WHITESPACE; 1908 break; 1909 case CHAR_COMPACT_OPTIONAL_WHITESPACE: 1910 m->str_flags |= 1911 STRING_COMPACT_OPTIONAL_WHITESPACE; 1912 break; 1913 case CHAR_IGNORE_LOWERCASE: 1914 m->str_flags |= STRING_IGNORE_LOWERCASE; 1915 break; 1916 case CHAR_IGNORE_UPPERCASE: 1917 m->str_flags |= STRING_IGNORE_UPPERCASE; 1918 break; 1919 case CHAR_REGEX_OFFSET_START: 1920 m->str_flags |= REGEX_OFFSET_START; 1921 break; 1922 case CHAR_BINTEST: 1923 m->str_flags |= STRING_BINTEST; 1924 break; 1925 case CHAR_TEXTTEST: 1926 m->str_flags |= STRING_TEXTTEST; 1927 break; 1928 case CHAR_TRIM: 1929 m->str_flags |= STRING_TRIM; 1930 break; 1931 case CHAR_PSTRING_1_LE: 1932 if (m->type != FILE_PSTRING) 1933 goto bad; 1934 m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_1_LE; 1935 break; 1936 case CHAR_PSTRING_2_BE: 1937 if (m->type != FILE_PSTRING) 1938 goto bad; 1939 m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_2_BE; 1940 break; 1941 case CHAR_PSTRING_2_LE: 1942 if (m->type != FILE_PSTRING) 1943 goto bad; 1944 m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_2_LE; 1945 break; 1946 case CHAR_PSTRING_4_BE: 1947 if (m->type != FILE_PSTRING) 1948 goto bad; 1949 m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_4_BE; 1950 break; 1951 case CHAR_PSTRING_4_LE: 1952 switch (m->type) { 1953 case FILE_PSTRING: 1954 case FILE_REGEX: 1955 break; 1956 default: 1957 goto bad; 1958 } 1959 m->str_flags = (m->str_flags & ~PSTRING_LEN) | PSTRING_4_LE; 1960 break; 1961 case CHAR_PSTRING_LENGTH_INCLUDES_ITSELF: 1962 if (m->type != FILE_PSTRING) 1963 goto bad; 1964 m->str_flags |= PSTRING_LENGTH_INCLUDES_ITSELF; 1965 break; 1966 default: 1967 bad: 1968 if (ms->flags & MAGIC_CHECK) 1969 file_magwarn(ms, 1970 "string extension `%c' " 1971 "invalid", *l); 1972 return -1; 1973 } 1974 /* allow multiple '/' for readability */ 1975 if (l[1] == '/' && 1976 !isspace((unsigned char)l[2])) 1977 l++; | 2016 if (IS_STRING(m->type)) { 2017 int r; 2018 2019 if (op != FILE_OPDIVIDE) { 2020 if (ms->flags & MAGIC_CHECK) 2021 file_magwarn(ms, 2022 "invalid string/indirect op: " 2023 "`%c'", *t); 2024 return -1; |
1978 } | 2025 } |
1979 if (string_modifier_check(ms, m) == -1) | 2026 2027 if (m->type == FILE_INDIRECT) 2028 r = parse_indirect_modifier(ms, m, &l); 2029 else 2030 r = parse_string_modifier(ms, m, &l); 2031 if (r == -1) |
1980 return -1; | 2032 return -1; |
1981 } 1982 else { 1983 if (ms->flags & MAGIC_CHECK) 1984 file_magwarn(ms, "invalid string op: %c", *t); 1985 return -1; 1986 } | 2033 } else 2034 parse_op_modifier(ms, m, &l, op); |
1987 } | 2035 } |
2036 |
|
1988 /* 1989 * We used to set mask to all 1's here, instead let's just not do 1990 * anything if mask = 0 (unless you have a better idea) 1991 */ 1992 EATAB; 1993 1994 switch (*l) { 1995 case '>': --- 1197 unchanged lines hidden --- | 2037 /* 2038 * We used to set mask to all 1's here, instead let's just not do 2039 * anything if mask = 0 (unless you have a better idea) 2040 */ 2041 EATAB; 2042 2043 switch (*l) { 2044 case '>': --- 1197 unchanged lines hidden --- |