Deleted Added
full compact
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 ---