Commit 2e7c42943d248083bae01fa5a6a84199fbbc8887

Authored by decalage2
1 parent 435baf80

colorclass is now an external dependency, obsolete copy removed from thirdparty folder

oletools/oledir.py
@@ -51,6 +51,7 @@ from __future__ import print_function @@ -51,6 +51,7 @@ from __future__ import print_function
51 # 2018-04-11 v0.53 PL: - added table displaying storage tree and CLSIDs 51 # 2018-04-11 v0.53 PL: - added table displaying storage tree and CLSIDs
52 # 2018-04-13 PL: - moved KNOWN_CLSIDS to common.clsid 52 # 2018-04-13 PL: - moved KNOWN_CLSIDS to common.clsid
53 # 2018-08-28 v0.54 PL: - olefile is now a dependency 53 # 2018-08-28 v0.54 PL: - olefile is now a dependency
  54 +# 2018-10-06 - colorclass is now a dependency
54 55
55 __version__ = '0.54dev1' 56 __version__ = '0.54dev1'
56 57
@@ -63,6 +64,13 @@ __version__ = '0.54dev1' @@ -63,6 +64,13 @@ __version__ = '0.54dev1'
63 64
64 import sys, os, optparse 65 import sys, os, optparse
65 66
  67 +import olefile
  68 +import colorclass
  69 +
  70 +# On Windows, colorclass needs to be enabled:
  71 +if os.name == 'nt':
  72 + colorclass.Windows.enable(auto_colors=True)
  73 +
66 # IMPORTANT: it should be possible to run oletools directly as scripts 74 # IMPORTANT: it should be possible to run oletools directly as scripts
67 # in any directory without installing them with pip or setup.py. 75 # in any directory without installing them with pip or setup.py.
68 # In that case, relative imports are NOT usable. 76 # In that case, relative imports are NOT usable.
@@ -75,20 +83,6 @@ _parent_dir = os.path.normpath(os.path.join(_thismodule_dir, '..')) @@ -75,20 +83,6 @@ _parent_dir = os.path.normpath(os.path.join(_thismodule_dir, '..'))
75 if not _parent_dir in sys.path: 83 if not _parent_dir in sys.path:
76 sys.path.insert(0, _parent_dir) 84 sys.path.insert(0, _parent_dir)
77 85
78 -# we also need the thirdparty dir for colorclass  
79 -# TODO: remove colorclass from thirdparty, make it a dependency  
80 -_thirdparty_dir = os.path.normpath(os.path.join(_thismodule_dir, 'thirdparty'))  
81 -# print('_thirdparty_dir = %r' % _thirdparty_dir)  
82 -if not _thirdparty_dir in sys.path:  
83 - sys.path.insert(0, _thirdparty_dir)  
84 -  
85 -import colorclass  
86 -  
87 -# On Windows, colorclass needs to be enabled:  
88 -if os.name == 'nt':  
89 - colorclass.Windows.enable(auto_colors=True)  
90 -  
91 -import olefile  
92 from oletools.thirdparty.tablestream import tablestream 86 from oletools.thirdparty.tablestream import tablestream
93 from oletools.thirdparty.xglob import xglob 87 from oletools.thirdparty.xglob import xglob
94 from oletools.common.clsid import KNOWN_CLSIDS 88 from oletools.common.clsid import KNOWN_CLSIDS
oletools/thirdparty/colorclass/LICENSE.txt deleted
1 -The MIT License (MIT)  
2 -  
3 -Copyright (c) 2014 Robpol86  
4 -  
5 -Permission is hereby granted, free of charge, to any person obtaining a copy  
6 -of this software and associated documentation files (the "Software"), to deal  
7 -in the Software without restriction, including without limitation the rights  
8 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
9 -copies of the Software, and to permit persons to whom the Software is  
10 -furnished to do so, subject to the following conditions:  
11 -  
12 -The above copyright notice and this permission notice shall be included in all  
13 -copies or substantial portions of the Software.  
14 -  
15 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
16 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
17 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
18 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
19 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
20 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
21 -SOFTWARE.  
oletools/thirdparty/colorclass/__init__.py deleted
1 -"""Colorful worry-free console applications for Linux, Mac OS X, and Windows.  
2 -  
3 -Supported natively on Linux and Mac OSX (Just Works), and on Windows it works the same if Windows.enable() is called.  
4 -  
5 -Gives you expected and sane results from methods like len() and .capitalize().  
6 -  
7 -https://github.com/Robpol86/colorclass  
8 -https://pypi.org/project/colorclass/  
9 -"""  
10 -  
11 -from colorclass.codes import list_tags # noqa  
12 -from colorclass.color import Color # noqa  
13 -from colorclass.toggles import disable_all_colors # noqa  
14 -from colorclass.toggles import disable_if_no_tty # noqa  
15 -from colorclass.toggles import enable_all_colors # noqa  
16 -from colorclass.toggles import is_enabled # noqa  
17 -from colorclass.toggles import is_light # noqa  
18 -from colorclass.toggles import set_dark_background # noqa  
19 -from colorclass.toggles import set_light_background # noqa  
20 -from colorclass.windows import Windows # noqa  
21 -  
22 -  
23 -__all__ = (  
24 - 'Color',  
25 - 'disable_all_colors',  
26 - 'enable_all_colors',  
27 - 'is_enabled',  
28 - 'is_light',  
29 - 'list_tags',  
30 - 'set_dark_background',  
31 - 'set_light_background',  
32 - 'Windows',  
33 -)  
34 -  
35 -  
36 -__author__ = '@Robpol86'  
37 -__license__ = 'MIT'  
38 -__version__ = '2.2.0'  
oletools/thirdparty/colorclass/__main__.py deleted
1 -"""Called by "python -m". Allows package to be used as a script.  
2 -  
3 -Example usage:  
4 -echo "{red}Red{/red}" |python -m colorclass  
5 -"""  
6 -  
7 -from __future__ import print_function  
8 -  
9 -import fileinput  
10 -import os  
11 -  
12 -from colorclass.color import Color  
13 -from colorclass.toggles import disable_all_colors  
14 -from colorclass.toggles import enable_all_colors  
15 -from colorclass.toggles import set_dark_background  
16 -from colorclass.toggles import set_light_background  
17 -from colorclass.windows import Windows  
18 -  
19 -TRUTHY = ('true', '1', 'yes', 'on')  
20 -  
21 -  
22 -if __name__ == '__main__':  
23 - if os.environ.get('COLOR_ENABLE', '').lower() in TRUTHY:  
24 - enable_all_colors()  
25 - elif os.environ.get('COLOR_DISABLE', '').lower() in TRUTHY:  
26 - disable_all_colors()  
27 - if os.environ.get('COLOR_LIGHT', '').lower() in TRUTHY:  
28 - set_light_background()  
29 - elif os.environ.get('COLOR_DARK', '').lower() in TRUTHY:  
30 - set_dark_background()  
31 - Windows.enable()  
32 - for LINE in fileinput.input():  
33 - print(Color(LINE))  
oletools/thirdparty/colorclass/codes.py deleted
1 -"""Handles mapping between color names and ANSI codes and determining auto color codes."""  
2 -  
3 -import sys  
4 -from collections import Mapping  
5 -  
6 -BASE_CODES = {  
7 - '/all': 0, 'b': 1, 'f': 2, 'i': 3, 'u': 4, 'flash': 5, 'outline': 6, 'negative': 7, 'invis': 8, 'strike': 9,  
8 - '/b': 22, '/f': 22, '/i': 23, '/u': 24, '/flash': 25, '/outline': 26, '/negative': 27, '/invis': 28,  
9 - '/strike': 29, '/fg': 39, '/bg': 49,  
10 -  
11 - 'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37,  
12 -  
13 - 'bgblack': 40, 'bgred': 41, 'bggreen': 42, 'bgyellow': 43, 'bgblue': 44, 'bgmagenta': 45, 'bgcyan': 46,  
14 - 'bgwhite': 47,  
15 -  
16 - 'hiblack': 90, 'hired': 91, 'higreen': 92, 'hiyellow': 93, 'hiblue': 94, 'himagenta': 95, 'hicyan': 96,  
17 - 'hiwhite': 97,  
18 -  
19 - 'hibgblack': 100, 'hibgred': 101, 'hibggreen': 102, 'hibgyellow': 103, 'hibgblue': 104, 'hibgmagenta': 105,  
20 - 'hibgcyan': 106, 'hibgwhite': 107,  
21 -  
22 - 'autored': None, 'autoblack': None, 'automagenta': None, 'autowhite': None, 'autoblue': None, 'autoyellow': None,  
23 - 'autogreen': None, 'autocyan': None,  
24 -  
25 - 'autobgred': None, 'autobgblack': None, 'autobgmagenta': None, 'autobgwhite': None, 'autobgblue': None,  
26 - 'autobgyellow': None, 'autobggreen': None, 'autobgcyan': None,  
27 -  
28 - '/black': 39, '/red': 39, '/green': 39, '/yellow': 39, '/blue': 39, '/magenta': 39, '/cyan': 39, '/white': 39,  
29 - '/hiblack': 39, '/hired': 39, '/higreen': 39, '/hiyellow': 39, '/hiblue': 39, '/himagenta': 39, '/hicyan': 39,  
30 - '/hiwhite': 39,  
31 -  
32 - '/bgblack': 49, '/bgred': 49, '/bggreen': 49, '/bgyellow': 49, '/bgblue': 49, '/bgmagenta': 49, '/bgcyan': 49,  
33 - '/bgwhite': 49, '/hibgblack': 49, '/hibgred': 49, '/hibggreen': 49, '/hibgyellow': 49, '/hibgblue': 49,  
34 - '/hibgmagenta': 49, '/hibgcyan': 49, '/hibgwhite': 49,  
35 -  
36 - '/autored': 39, '/autoblack': 39, '/automagenta': 39, '/autowhite': 39, '/autoblue': 39, '/autoyellow': 39,  
37 - '/autogreen': 39, '/autocyan': 39,  
38 -  
39 - '/autobgred': 49, '/autobgblack': 49, '/autobgmagenta': 49, '/autobgwhite': 49, '/autobgblue': 49,  
40 - '/autobgyellow': 49, '/autobggreen': 49, '/autobgcyan': 49,  
41 -}  
42 -  
43 -  
44 -class ANSICodeMapping(Mapping):  
45 - """Read-only dictionary, resolves closing tags and automatic colors. Iterates only used color tags.  
46 -  
47 - :cvar bool DISABLE_COLORS: Disable colors (strip color codes).  
48 - :cvar bool LIGHT_BACKGROUND: Use low intensity color codes.  
49 - """  
50 -  
51 - DISABLE_COLORS = False  
52 - LIGHT_BACKGROUND = False  
53 -  
54 - def __init__(self, value_markup):  
55 - """Constructor.  
56 -  
57 - :param str value_markup: String with {color} tags.  
58 - """  
59 - self.whitelist = [k for k in BASE_CODES if '{' + k + '}' in value_markup]  
60 -  
61 - def __getitem__(self, item):  
62 - """Return value for key or None if colors are disabled.  
63 -  
64 - :param str item: Key.  
65 -  
66 - :return: Color code integer.  
67 - :rtype: int  
68 - """  
69 - if item not in self.whitelist:  
70 - raise KeyError(item)  
71 - if self.DISABLE_COLORS:  
72 - return None  
73 - return getattr(self, item, BASE_CODES[item])  
74 -  
75 - def __iter__(self):  
76 - """Iterate dictionary."""  
77 - return iter(self.whitelist)  
78 -  
79 - def __len__(self):  
80 - """Dictionary length."""  
81 - return len(self.whitelist)  
82 -  
83 - @classmethod  
84 - def disable_all_colors(cls):  
85 - """Disable all colors. Strips any color tags or codes."""  
86 - cls.DISABLE_COLORS = True  
87 -  
88 - @classmethod  
89 - def enable_all_colors(cls):  
90 - """Enable all colors. Strips any color tags or codes."""  
91 - cls.DISABLE_COLORS = False  
92 -  
93 - @classmethod  
94 - def disable_if_no_tty(cls):  
95 - """Disable all colors only if there is no TTY available.  
96 -  
97 - :return: True if colors are disabled, False if stderr or stdout is a TTY.  
98 - :rtype: bool  
99 - """  
100 - if sys.stdout.isatty() or sys.stderr.isatty():  
101 - return False  
102 - cls.disable_all_colors()  
103 - return True  
104 -  
105 - @classmethod  
106 - def set_dark_background(cls):  
107 - """Choose dark colors for all 'auto'-prefixed codes for readability on light backgrounds."""  
108 - cls.LIGHT_BACKGROUND = False  
109 -  
110 - @classmethod  
111 - def set_light_background(cls):  
112 - """Choose dark colors for all 'auto'-prefixed codes for readability on light backgrounds."""  
113 - cls.LIGHT_BACKGROUND = True  
114 -  
115 - @property  
116 - def autoblack(self):  
117 - """Return automatic black foreground color depending on background color."""  
118 - return BASE_CODES['black' if ANSICodeMapping.LIGHT_BACKGROUND else 'hiblack']  
119 -  
120 - @property  
121 - def autored(self):  
122 - """Return automatic red foreground color depending on background color."""  
123 - return BASE_CODES['red' if ANSICodeMapping.LIGHT_BACKGROUND else 'hired']  
124 -  
125 - @property  
126 - def autogreen(self):  
127 - """Return automatic green foreground color depending on background color."""  
128 - return BASE_CODES['green' if ANSICodeMapping.LIGHT_BACKGROUND else 'higreen']  
129 -  
130 - @property  
131 - def autoyellow(self):  
132 - """Return automatic yellow foreground color depending on background color."""  
133 - return BASE_CODES['yellow' if ANSICodeMapping.LIGHT_BACKGROUND else 'hiyellow']  
134 -  
135 - @property  
136 - def autoblue(self):  
137 - """Return automatic blue foreground color depending on background color."""  
138 - return BASE_CODES['blue' if ANSICodeMapping.LIGHT_BACKGROUND else 'hiblue']  
139 -  
140 - @property  
141 - def automagenta(self):  
142 - """Return automatic magenta foreground color depending on background color."""  
143 - return BASE_CODES['magenta' if ANSICodeMapping.LIGHT_BACKGROUND else 'himagenta']  
144 -  
145 - @property  
146 - def autocyan(self):  
147 - """Return automatic cyan foreground color depending on background color."""  
148 - return BASE_CODES['cyan' if ANSICodeMapping.LIGHT_BACKGROUND else 'hicyan']  
149 -  
150 - @property  
151 - def autowhite(self):  
152 - """Return automatic white foreground color depending on background color."""  
153 - return BASE_CODES['white' if ANSICodeMapping.LIGHT_BACKGROUND else 'hiwhite']  
154 -  
155 - @property  
156 - def autobgblack(self):  
157 - """Return automatic black background color depending on background color."""  
158 - return BASE_CODES['bgblack' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgblack']  
159 -  
160 - @property  
161 - def autobgred(self):  
162 - """Return automatic red background color depending on background color."""  
163 - return BASE_CODES['bgred' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgred']  
164 -  
165 - @property  
166 - def autobggreen(self):  
167 - """Return automatic green background color depending on background color."""  
168 - return BASE_CODES['bggreen' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibggreen']  
169 -  
170 - @property  
171 - def autobgyellow(self):  
172 - """Return automatic yellow background color depending on background color."""  
173 - return BASE_CODES['bgyellow' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgyellow']  
174 -  
175 - @property  
176 - def autobgblue(self):  
177 - """Return automatic blue background color depending on background color."""  
178 - return BASE_CODES['bgblue' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgblue']  
179 -  
180 - @property  
181 - def autobgmagenta(self):  
182 - """Return automatic magenta background color depending on background color."""  
183 - return BASE_CODES['bgmagenta' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgmagenta']  
184 -  
185 - @property  
186 - def autobgcyan(self):  
187 - """Return automatic cyan background color depending on background color."""  
188 - return BASE_CODES['bgcyan' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgcyan']  
189 -  
190 - @property  
191 - def autobgwhite(self):  
192 - """Return automatic white background color depending on background color."""  
193 - return BASE_CODES['bgwhite' if ANSICodeMapping.LIGHT_BACKGROUND else 'hibgwhite']  
194 -  
195 -  
196 -def list_tags():  
197 - """List the available tags.  
198 -  
199 - :return: List of 4-item tuples: opening tag, closing tag, main ansi value, closing ansi value.  
200 - :rtype: list  
201 - """  
202 - # Build reverse dictionary. Keys are closing tags, values are [closing ansi, opening tag, opening ansi].  
203 - reverse_dict = dict()  
204 - for tag, ansi in sorted(BASE_CODES.items()):  
205 - if tag.startswith('/'):  
206 - reverse_dict[tag] = [ansi, None, None]  
207 - else:  
208 - reverse_dict['/' + tag][1:] = [tag, ansi]  
209 -  
210 - # Collapse  
211 - four_item_tuples = [(v[1], k, v[2], v[0]) for k, v in reverse_dict.items()]  
212 -  
213 - # Sort.  
214 - def sorter(four_item):  
215 - """Sort /all /fg /bg first, then b i u flash, then auto colors, then dark colors, finally light colors.  
216 -  
217 - :param iter four_item: [opening tag, closing tag, main ansi value, closing ansi value]  
218 -  
219 - :return Sorting weight.  
220 - :rtype: int  
221 - """  
222 - if not four_item[2]: # /all /fg /bg  
223 - return four_item[3] - 200  
224 - if four_item[2] < 10 or four_item[0].startswith('auto'): # b f i u or auto colors  
225 - return four_item[2] - 100  
226 - return four_item[2]  
227 - four_item_tuples.sort(key=sorter)  
228 -  
229 - return four_item_tuples  
oletools/thirdparty/colorclass/color.py deleted
1 -"""Color class used by library users."""  
2 -  
3 -from colorclass.core import ColorStr  
4 -  
5 -  
6 -class Color(ColorStr):  
7 - """Unicode (str in Python3) subclass with ANSI terminal text color support.  
8 -  
9 - Example syntax: Color('{red}Sample Text{/red}')  
10 -  
11 - Example without parsing logic: Color('{red}Sample Text{/red}', keep_tags=True)  
12 -  
13 - For a list of codes, call: colorclass.list_tags()  
14 - """  
15 -  
16 - @classmethod  
17 - def colorize(cls, color, string, auto=False):  
18 - """Color-code entire string using specified color.  
19 -  
20 - :param str color: Color of string.  
21 - :param str string: String to colorize.  
22 - :param bool auto: Enable auto-color (dark/light terminal).  
23 -  
24 - :return: Class instance for colorized string.  
25 - :rtype: Color  
26 - """  
27 - tag = '{0}{1}'.format('auto' if auto else '', color)  
28 - return cls('{%s}%s{/%s}' % (tag, string, tag))  
29 -  
30 - @classmethod  
31 - def black(cls, string, auto=False):  
32 - """Color-code entire string.  
33 -  
34 - :param str string: String to colorize.  
35 - :param bool auto: Enable auto-color (dark/light terminal).  
36 -  
37 - :return: Class instance for colorized string.  
38 - :rtype: Color  
39 - """  
40 - return cls.colorize('black', string, auto=auto)  
41 -  
42 - @classmethod  
43 - def bgblack(cls, string, auto=False):  
44 - """Color-code entire string.  
45 -  
46 - :param str string: String to colorize.  
47 - :param bool auto: Enable auto-color (dark/light terminal).  
48 -  
49 - :return: Class instance for colorized string.  
50 - :rtype: Color  
51 - """  
52 - return cls.colorize('bgblack', string, auto=auto)  
53 -  
54 - @classmethod  
55 - def red(cls, string, auto=False):  
56 - """Color-code entire string.  
57 -  
58 - :param str string: String to colorize.  
59 - :param bool auto: Enable auto-color (dark/light terminal).  
60 -  
61 - :return: Class instance for colorized string.  
62 - :rtype: Color  
63 - """  
64 - return cls.colorize('red', string, auto=auto)  
65 -  
66 - @classmethod  
67 - def bgred(cls, string, auto=False):  
68 - """Color-code entire string.  
69 -  
70 - :param str string: String to colorize.  
71 - :param bool auto: Enable auto-color (dark/light terminal).  
72 -  
73 - :return: Class instance for colorized string.  
74 - :rtype: Color  
75 - """  
76 - return cls.colorize('bgred', string, auto=auto)  
77 -  
78 - @classmethod  
79 - def green(cls, string, auto=False):  
80 - """Color-code entire string.  
81 -  
82 - :param str string: String to colorize.  
83 - :param bool auto: Enable auto-color (dark/light terminal).  
84 -  
85 - :return: Class instance for colorized string.  
86 - :rtype: Color  
87 - """  
88 - return cls.colorize('green', string, auto=auto)  
89 -  
90 - @classmethod  
91 - def bggreen(cls, string, auto=False):  
92 - """Color-code entire string.  
93 -  
94 - :param str string: String to colorize.  
95 - :param bool auto: Enable auto-color (dark/light terminal).  
96 -  
97 - :return: Class instance for colorized string.  
98 - :rtype: Color  
99 - """  
100 - return cls.colorize('bggreen', string, auto=auto)  
101 -  
102 - @classmethod  
103 - def yellow(cls, string, auto=False):  
104 - """Color-code entire string.  
105 -  
106 - :param str string: String to colorize.  
107 - :param bool auto: Enable auto-color (dark/light terminal).  
108 -  
109 - :return: Class instance for colorized string.  
110 - :rtype: Color  
111 - """  
112 - return cls.colorize('yellow', string, auto=auto)  
113 -  
114 - @classmethod  
115 - def bgyellow(cls, string, auto=False):  
116 - """Color-code entire string.  
117 -  
118 - :param str string: String to colorize.  
119 - :param bool auto: Enable auto-color (dark/light terminal).  
120 -  
121 - :return: Class instance for colorized string.  
122 - :rtype: Color  
123 - """  
124 - return cls.colorize('bgyellow', string, auto=auto)  
125 -  
126 - @classmethod  
127 - def blue(cls, string, auto=False):  
128 - """Color-code entire string.  
129 -  
130 - :param str string: String to colorize.  
131 - :param bool auto: Enable auto-color (dark/light terminal).  
132 -  
133 - :return: Class instance for colorized string.  
134 - :rtype: Color  
135 - """  
136 - return cls.colorize('blue', string, auto=auto)  
137 -  
138 - @classmethod  
139 - def bgblue(cls, string, auto=False):  
140 - """Color-code entire string.  
141 -  
142 - :param str string: String to colorize.  
143 - :param bool auto: Enable auto-color (dark/light terminal).  
144 -  
145 - :return: Class instance for colorized string.  
146 - :rtype: Color  
147 - """  
148 - return cls.colorize('bgblue', string, auto=auto)  
149 -  
150 - @classmethod  
151 - def magenta(cls, string, auto=False):  
152 - """Color-code entire string.  
153 -  
154 - :param str string: String to colorize.  
155 - :param bool auto: Enable auto-color (dark/light terminal).  
156 -  
157 - :return: Class instance for colorized string.  
158 - :rtype: Color  
159 - """  
160 - return cls.colorize('magenta', string, auto=auto)  
161 -  
162 - @classmethod  
163 - def bgmagenta(cls, string, auto=False):  
164 - """Color-code entire string.  
165 -  
166 - :param str string: String to colorize.  
167 - :param bool auto: Enable auto-color (dark/light terminal).  
168 -  
169 - :return: Class instance for colorized string.  
170 - :rtype: Color  
171 - """  
172 - return cls.colorize('bgmagenta', string, auto=auto)  
173 -  
174 - @classmethod  
175 - def cyan(cls, string, auto=False):  
176 - """Color-code entire string.  
177 -  
178 - :param str string: String to colorize.  
179 - :param bool auto: Enable auto-color (dark/light terminal).  
180 -  
181 - :return: Class instance for colorized string.  
182 - :rtype: Color  
183 - """  
184 - return cls.colorize('cyan', string, auto=auto)  
185 -  
186 - @classmethod  
187 - def bgcyan(cls, string, auto=False):  
188 - """Color-code entire string.  
189 -  
190 - :param str string: String to colorize.  
191 - :param bool auto: Enable auto-color (dark/light terminal).  
192 -  
193 - :return: Class instance for colorized string.  
194 - :rtype: Color  
195 - """  
196 - return cls.colorize('bgcyan', string, auto=auto)  
197 -  
198 - @classmethod  
199 - def white(cls, string, auto=False):  
200 - """Color-code entire string.  
201 -  
202 - :param str string: String to colorize.  
203 - :param bool auto: Enable auto-color (dark/light terminal).  
204 -  
205 - :return: Class instance for colorized string.  
206 - :rtype: Color  
207 - """  
208 - return cls.colorize('white', string, auto=auto)  
209 -  
210 - @classmethod  
211 - def bgwhite(cls, string, auto=False):  
212 - """Color-code entire string.  
213 -  
214 - :param str string: String to colorize.  
215 - :param bool auto: Enable auto-color (dark/light terminal).  
216 -  
217 - :return: Class instance for colorized string.  
218 - :rtype: Color  
219 - """  
220 - return cls.colorize('bgwhite', string, auto=auto)  
oletools/thirdparty/colorclass/core.py deleted
1 -"""String subclass that handles ANSI color codes."""  
2 -  
3 -from colorclass.codes import ANSICodeMapping  
4 -from colorclass.parse import parse_input, RE_SPLIT  
5 -from colorclass.search import build_color_index, find_char_color  
6 -  
7 -PARENT_CLASS = type(u'')  
8 -  
9 -  
10 -def apply_text(incoming, func):  
11 - """Call `func` on text portions of incoming color string.  
12 -  
13 - :param iter incoming: Incoming string/ColorStr/string-like object to iterate.  
14 - :param func: Function to call with string portion as first and only parameter.  
15 -  
16 - :return: Modified string, same class type as incoming string.  
17 - """  
18 - split = RE_SPLIT.split(incoming)  
19 - for i, item in enumerate(split):  
20 - if not item or RE_SPLIT.match(item):  
21 - continue  
22 - split[i] = func(item)  
23 - return incoming.__class__().join(split)  
24 -  
25 -  
26 -class ColorBytes(bytes):  
27 - """Str (bytes in Python3) subclass, .decode() overridden to return unicode (str in Python3) subclass instance."""  
28 -  
29 - def __new__(cls, *args, **kwargs):  
30 - """Save original class so decode() returns an instance of it."""  
31 - original_class = kwargs.pop('original_class')  
32 - combined_args = [cls] + list(args)  
33 - instance = bytes.__new__(*combined_args, **kwargs)  
34 - instance.original_class = original_class  
35 - return instance  
36 -  
37 - def decode(self, encoding='utf-8', errors='strict'):  
38 - """Decode using the codec registered for encoding. Default encoding is 'utf-8'.  
39 -  
40 - errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors  
41 - raise a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' as well as any other name  
42 - registered with codecs.register_error that is able to handle UnicodeDecodeErrors.  
43 -  
44 - :param str encoding: Codec.  
45 - :param str errors: Error handling scheme.  
46 - """  
47 - original_class = getattr(self, 'original_class')  
48 - return original_class(super(ColorBytes, self).decode(encoding, errors))  
49 -  
50 -  
51 -class ColorStr(PARENT_CLASS):  
52 - """Core color class."""  
53 -  
54 - def __new__(cls, *args, **kwargs):  
55 - """Parse color markup and instantiate."""  
56 - keep_tags = kwargs.pop('keep_tags', False)  
57 -  
58 - # Parse string.  
59 - value_markup = args[0] if args else PARENT_CLASS() # e.g. '{red}test{/red}'  
60 - value_colors, value_no_colors = parse_input(value_markup, ANSICodeMapping.DISABLE_COLORS, keep_tags)  
61 - color_index = build_color_index(value_colors)  
62 -  
63 - # Instantiate.  
64 - color_args = [cls, value_colors] + list(args[1:])  
65 - instance = PARENT_CLASS.__new__(*color_args, **kwargs)  
66 -  
67 - # Add additional attributes and return.  
68 - instance.value_colors = value_colors  
69 - instance.value_no_colors = value_no_colors  
70 - instance.has_colors = value_colors != value_no_colors  
71 - instance.color_index = color_index  
72 - return instance  
73 -  
74 - def __add__(self, other):  
75 - """Concatenate."""  
76 - return self.__class__(self.value_colors + other, keep_tags=True)  
77 -  
78 - def __getitem__(self, item):  
79 - """Retrieve character."""  
80 - try:  
81 - color_pos = self.color_index[int(item)]  
82 - except TypeError: # slice  
83 - return super(ColorStr, self).__getitem__(item)  
84 - return self.__class__(find_char_color(self.value_colors, color_pos), keep_tags=True)  
85 -  
86 - def __iter__(self):  
87 - """Yield one color-coded character at a time."""  
88 - for color_pos in self.color_index:  
89 - yield self.__class__(find_char_color(self.value_colors, color_pos))  
90 -  
91 - def __len__(self):  
92 - """Length of string without color codes (what users expect)."""  
93 - return self.value_no_colors.__len__()  
94 -  
95 - def __mod__(self, other):  
96 - """String substitution (like printf)."""  
97 - return self.__class__(self.value_colors % other, keep_tags=True)  
98 -  
99 - def __mul__(self, other):  
100 - """Multiply string."""  
101 - return self.__class__(self.value_colors * other, keep_tags=True)  
102 -  
103 - def __repr__(self):  
104 - """Representation of a class instance (like datetime.datetime.now())."""  
105 - return '{name}({value})'.format(name=self.__class__.__name__, value=repr(self.value_colors))  
106 -  
107 - def capitalize(self):  
108 - """Return a copy of the string with only its first character capitalized."""  
109 - return apply_text(self, lambda s: s.capitalize())  
110 -  
111 - def center(self, width, fillchar=None):  
112 - """Return centered in a string of length width. Padding is done using the specified fill character or space.  
113 -  
114 - :param int width: Length of output string.  
115 - :param str fillchar: Use this character instead of spaces.  
116 - """  
117 - if fillchar is not None:  
118 - result = self.value_no_colors.center(width, fillchar)  
119 - else:  
120 - result = self.value_no_colors.center(width)  
121 - return self.__class__(result.replace(self.value_no_colors, self.value_colors), keep_tags=True)  
122 -  
123 - def count(self, sub, start=0, end=-1):  
124 - """Return the number of non-overlapping occurrences of substring sub in string[start:end].  
125 -  
126 - Optional arguments start and end are interpreted as in slice notation.  
127 -  
128 - :param str sub: Substring to search.  
129 - :param int start: Beginning position.  
130 - :param int end: Stop comparison at this position.  
131 - """  
132 - return self.value_no_colors.count(sub, start, end)  
133 -  
134 - def endswith(self, suffix, start=0, end=None):  
135 - """Return True if ends with the specified suffix, False otherwise.  
136 -  
137 - With optional start, test beginning at that position. With optional end, stop comparing at that position.  
138 - suffix can also be a tuple of strings to try.  
139 -  
140 - :param str suffix: Suffix to search.  
141 - :param int start: Beginning position.  
142 - :param int end: Stop comparison at this position.  
143 - """  
144 - args = [suffix, start] + ([] if end is None else [end])  
145 - return self.value_no_colors.endswith(*args)  
146 -  
147 - def encode(self, encoding=None, errors='strict'):  
148 - """Encode using the codec registered for encoding. encoding defaults to the default encoding.  
149 -  
150 - errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors  
151 - raise a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any  
152 - other name registered with codecs.register_error that is able to handle UnicodeEncodeErrors.  
153 -  
154 - :param str encoding: Codec.  
155 - :param str errors: Error handling scheme.  
156 - """  
157 - return ColorBytes(super(ColorStr, self).encode(encoding, errors), original_class=self.__class__)  
158 -  
159 - def decode(self, encoding=None, errors='strict'):  
160 - """Decode using the codec registered for encoding. encoding defaults to the default encoding.  
161 -  
162 - errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors  
163 - raise a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' as well as any other name  
164 - registered with codecs.register_error that is able to handle UnicodeDecodeErrors.  
165 -  
166 - :param str encoding: Codec.  
167 - :param str errors: Error handling scheme.  
168 - """  
169 - return self.__class__(super(ColorStr, self).decode(encoding, errors), keep_tags=True)  
170 -  
171 - def find(self, sub, start=None, end=None):  
172 - """Return the lowest index where substring sub is found, such that sub is contained within string[start:end].  
173 -  
174 - Optional arguments start and end are interpreted as in slice notation.  
175 -  
176 - :param str sub: Substring to search.  
177 - :param int start: Beginning position.  
178 - :param int end: Stop comparison at this position.  
179 - """  
180 - return self.value_no_colors.find(sub, start, end)  
181 -  
182 - def format(self, *args, **kwargs):  
183 - """Return a formatted version, using substitutions from args and kwargs.  
184 -  
185 - The substitutions are identified by braces ('{' and '}').  
186 - """  
187 - return self.__class__(super(ColorStr, self).format(*args, **kwargs), keep_tags=True)  
188 -  
189 - def index(self, sub, start=None, end=None):  
190 - """Like S.find() but raise ValueError when the substring is not found.  
191 -  
192 - :param str sub: Substring to search.  
193 - :param int start: Beginning position.  
194 - :param int end: Stop comparison at this position.  
195 - """  
196 - return self.value_no_colors.index(sub, start, end)  
197 -  
198 - def isalnum(self):  
199 - """Return True if all characters in string are alphanumeric and there is at least one character in it."""  
200 - return self.value_no_colors.isalnum()  
201 -  
202 - def isalpha(self):  
203 - """Return True if all characters in string are alphabetic and there is at least one character in it."""  
204 - return self.value_no_colors.isalpha()  
205 -  
206 - def isdecimal(self):  
207 - """Return True if there are only decimal characters in string, False otherwise."""  
208 - return self.value_no_colors.isdecimal()  
209 -  
210 - def isdigit(self):  
211 - """Return True if all characters in string are digits and there is at least one character in it."""  
212 - return self.value_no_colors.isdigit()  
213 -  
214 - def isnumeric(self):  
215 - """Return True if there are only numeric characters in string, False otherwise."""  
216 - return self.value_no_colors.isnumeric()  
217 -  
218 - def isspace(self):  
219 - """Return True if all characters in string are whitespace and there is at least one character in it."""  
220 - return self.value_no_colors.isspace()  
221 -  
222 - def istitle(self):  
223 - """Return True if string is a titlecased string and there is at least one character in it.  
224 -  
225 - That is uppercase characters may only follow uncased characters and lowercase characters only cased ones. Return  
226 - False otherwise.  
227 - """  
228 - return self.value_no_colors.istitle()  
229 -  
230 - def isupper(self):  
231 - """Return True if all cased characters are uppercase and there is at least one cased character in it."""  
232 - return self.value_no_colors.isupper()  
233 -  
234 - def join(self, iterable):  
235 - """Return a string which is the concatenation of the strings in the iterable.  
236 -  
237 - :param iterable: Join items in this iterable.  
238 - """  
239 - return self.__class__(super(ColorStr, self).join(iterable), keep_tags=True)  
240 -  
241 - def ljust(self, width, fillchar=None):  
242 - """Return left-justified string of length width. Padding is done using the specified fill character or space.  
243 -  
244 - :param int width: Length of output string.  
245 - :param str fillchar: Use this character instead of spaces.  
246 - """  
247 - if fillchar is not None:  
248 - result = self.value_no_colors.ljust(width, fillchar)  
249 - else:  
250 - result = self.value_no_colors.ljust(width)  
251 - return self.__class__(result.replace(self.value_no_colors, self.value_colors), keep_tags=True)  
252 -  
253 - def rfind(self, sub, start=None, end=None):  
254 - """Return the highest index where substring sub is found, such that sub is contained within string[start:end].  
255 -  
256 - Optional arguments start and end are interpreted as in slice notation.  
257 -  
258 - :param str sub: Substring to search.  
259 - :param int start: Beginning position.  
260 - :param int end: Stop comparison at this position.  
261 - """  
262 - return self.value_no_colors.rfind(sub, start, end)  
263 -  
264 - def rindex(self, sub, start=None, end=None):  
265 - """Like .rfind() but raise ValueError when the substring is not found.  
266 -  
267 - :param str sub: Substring to search.  
268 - :param int start: Beginning position.  
269 - :param int end: Stop comparison at this position.  
270 - """  
271 - return self.value_no_colors.rindex(sub, start, end)  
272 -  
273 - def rjust(self, width, fillchar=None):  
274 - """Return right-justified string of length width. Padding is done using the specified fill character or space.  
275 -  
276 - :param int width: Length of output string.  
277 - :param str fillchar: Use this character instead of spaces.  
278 - """  
279 - if fillchar is not None:  
280 - result = self.value_no_colors.rjust(width, fillchar)  
281 - else:  
282 - result = self.value_no_colors.rjust(width)  
283 - return self.__class__(result.replace(self.value_no_colors, self.value_colors), keep_tags=True)  
284 -  
285 - def splitlines(self, keepends=False):  
286 - """Return a list of the lines in the string, breaking at line boundaries.  
287 -  
288 - Line breaks are not included in the resulting list unless keepends is given and True.  
289 -  
290 - :param bool keepends: Include linebreaks.  
291 - """  
292 - return [self.__class__(l) for l in self.value_colors.splitlines(keepends)]  
293 -  
294 - def startswith(self, prefix, start=0, end=-1):  
295 - """Return True if string starts with the specified prefix, False otherwise.  
296 -  
297 - With optional start, test beginning at that position. With optional end, stop comparing at that position. prefix  
298 - can also be a tuple of strings to try.  
299 -  
300 - :param str prefix: Prefix to search.  
301 - :param int start: Beginning position.  
302 - :param int end: Stop comparison at this position.  
303 - """  
304 - return self.value_no_colors.startswith(prefix, start, end)  
305 -  
306 - def swapcase(self):  
307 - """Return a copy of the string with uppercase characters converted to lowercase and vice versa."""  
308 - return apply_text(self, lambda s: s.swapcase())  
309 -  
310 - def title(self):  
311 - """Return a titlecased version of the string.  
312 -  
313 - That is words start with uppercase characters, all remaining cased characters have lowercase.  
314 - """  
315 - return apply_text(self, lambda s: s.title())  
316 -  
317 - def translate(self, table):  
318 - """Return a copy of the string, where all characters have been mapped through the given translation table.  
319 -  
320 - Table must be a mapping of Unicode ordinals to Unicode ordinals, strings, or None. Unmapped characters are left  
321 - untouched. Characters mapped to None are deleted.  
322 -  
323 - :param table: Translation table.  
324 - """  
325 - return apply_text(self, lambda s: s.translate(table))  
326 -  
327 - def upper(self):  
328 - """Return a copy of the string converted to uppercase."""  
329 - return apply_text(self, lambda s: s.upper())  
330 -  
331 - def zfill(self, width):  
332 - """Pad a numeric string with zeros on the left, to fill a field of the specified width.  
333 -  
334 - The string is never truncated.  
335 -  
336 - :param int width: Length of output string.  
337 - """  
338 - if not self.value_no_colors:  
339 - result = self.value_no_colors.zfill(width)  
340 - else:  
341 - result = self.value_colors.replace(self.value_no_colors, self.value_no_colors.zfill(width))  
342 - return self.__class__(result, keep_tags=True)  
oletools/thirdparty/colorclass/parse.py deleted
1 -"""Parse color markup tags into ANSI escape sequences."""  
2 -  
3 -import re  
4 -  
5 -from colorclass.codes import ANSICodeMapping, BASE_CODES  
6 -  
7 -CODE_GROUPS = (  
8 - tuple(set(str(i) for i in BASE_CODES.values() if i and (40 <= i <= 49 or 100 <= i <= 109))), # bg colors  
9 - tuple(set(str(i) for i in BASE_CODES.values() if i and (30 <= i <= 39 or 90 <= i <= 99))), # fg colors  
10 - ('1', '22'), ('2', '22'), ('3', '23'), ('4', '24'), ('5', '25'), ('6', '26'), ('7', '27'), ('8', '28'), ('9', '29'),  
11 -)  
12 -RE_ANSI = re.compile(r'(\033\[([\d;]+)m)')  
13 -RE_COMBINE = re.compile(r'\033\[([\d;]+)m\033\[([\d;]+)m')  
14 -RE_SPLIT = re.compile(r'(\033\[[\d;]+m)')  
15 -  
16 -  
17 -def prune_overridden(ansi_string):  
18 - """Remove color codes that are rendered ineffective by subsequent codes in one escape sequence then sort codes.  
19 -  
20 - :param str ansi_string: Incoming ansi_string with ANSI color codes.  
21 -  
22 - :return: Color string with pruned color sequences.  
23 - :rtype: str  
24 - """  
25 - multi_seqs = set(p for p in RE_ANSI.findall(ansi_string) if ';' in p[1]) # Sequences with multiple color codes.  
26 -  
27 - for escape, codes in multi_seqs:  
28 - r_codes = list(reversed(codes.split(';')))  
29 -  
30 - # Nuke everything before {/all}.  
31 - try:  
32 - r_codes = r_codes[:r_codes.index('0') + 1]  
33 - except ValueError:  
34 - pass  
35 -  
36 - # Thin out groups.  
37 - for group in CODE_GROUPS:  
38 - for pos in reversed([i for i, n in enumerate(r_codes) if n in group][1:]):  
39 - r_codes.pop(pos)  
40 -  
41 - # Done.  
42 - reduced_codes = ';'.join(sorted(r_codes, key=int))  
43 - if codes != reduced_codes:  
44 - ansi_string = ansi_string.replace(escape, '\033[' + reduced_codes + 'm')  
45 -  
46 - return ansi_string  
47 -  
48 -  
49 -def parse_input(tagged_string, disable_colors, keep_tags):  
50 - """Perform the actual conversion of tags to ANSI escaped codes.  
51 -  
52 - Provides a version of the input without any colors for len() and other methods.  
53 -  
54 - :param str tagged_string: The input unicode value.  
55 - :param bool disable_colors: Strip all colors in both outputs.  
56 - :param bool keep_tags: Skip parsing curly bracket tags into ANSI escape sequences.  
57 -  
58 - :return: 2-item tuple. First item is the parsed output. Second item is a version of the input without any colors.  
59 - :rtype: tuple  
60 - """  
61 - codes = ANSICodeMapping(tagged_string)  
62 - output_colors = getattr(tagged_string, 'value_colors', tagged_string)  
63 -  
64 - # Convert: '{b}{red}' -> '\033[1m\033[31m'  
65 - if not keep_tags:  
66 - for tag, replacement in (('{' + k + '}', '' if v is None else '\033[%dm' % v) for k, v in codes.items()):  
67 - output_colors = output_colors.replace(tag, replacement)  
68 -  
69 - # Strip colors.  
70 - output_no_colors = RE_ANSI.sub('', output_colors)  
71 - if disable_colors:  
72 - return output_no_colors, output_no_colors  
73 -  
74 - # Combine: '\033[1m\033[31m' -> '\033[1;31m'  
75 - while True:  
76 - simplified = RE_COMBINE.sub(r'\033[\1;\2m', output_colors)  
77 - if simplified == output_colors:  
78 - break  
79 - output_colors = simplified  
80 -  
81 - # Prune: '\033[31;32;33;34;35m' -> '\033[35m'  
82 - output_colors = prune_overridden(output_colors)  
83 -  
84 - # Deduplicate: '\033[1;mT\033[1;mE\033[1;mS\033[1;mT' -> '\033[1;mTEST'  
85 - previous_escape = None  
86 - segments = list()  
87 - for item in (i for i in RE_SPLIT.split(output_colors) if i):  
88 - if RE_SPLIT.match(item):  
89 - if item != previous_escape:  
90 - segments.append(item)  
91 - previous_escape = item  
92 - else:  
93 - segments.append(item)  
94 - output_colors = ''.join(segments)  
95 -  
96 - return output_colors, output_no_colors  
oletools/thirdparty/colorclass/search.py deleted
1 -"""Determine color of characters that may or may not be adjacent to ANSI escape sequences."""  
2 -  
3 -from colorclass.parse import RE_SPLIT  
4 -  
5 -  
6 -def build_color_index(ansi_string):  
7 - """Build an index between visible characters and a string with invisible color codes.  
8 -  
9 - :param str ansi_string: String with color codes (ANSI escape sequences).  
10 -  
11 - :return: Position of visible characters in color string (indexes match non-color string).  
12 - :rtype: tuple  
13 - """  
14 - mapping = list()  
15 - color_offset = 0  
16 - for item in (i for i in RE_SPLIT.split(ansi_string) if i):  
17 - if RE_SPLIT.match(item):  
18 - color_offset += len(item)  
19 - else:  
20 - for _ in range(len(item)):  
21 - mapping.append(color_offset)  
22 - color_offset += 1  
23 - return tuple(mapping)  
24 -  
25 -  
26 -def find_char_color(ansi_string, pos):  
27 - """Determine what color a character is in the string.  
28 -  
29 - :param str ansi_string: String with color codes (ANSI escape sequences).  
30 - :param int pos: Position of the character in the ansi_string.  
31 -  
32 - :return: Character along with all surrounding color codes.  
33 - :rtype: str  
34 - """  
35 - result = list()  
36 - position = 0 # Set to None when character is found.  
37 - for item in (i for i in RE_SPLIT.split(ansi_string) if i):  
38 - if RE_SPLIT.match(item):  
39 - result.append(item)  
40 - if position is not None:  
41 - position += len(item)  
42 - elif position is not None:  
43 - for char in item:  
44 - if position == pos:  
45 - result.append(char)  
46 - position = None  
47 - break  
48 - position += 1  
49 - return ''.join(result)  
oletools/thirdparty/colorclass/toggles.py deleted
1 -"""Convenience functions to enable/disable features."""  
2 -  
3 -from colorclass.codes import ANSICodeMapping  
4 -  
5 -  
6 -def disable_all_colors():  
7 - """Disable all colors. Strip any color tags or codes."""  
8 - ANSICodeMapping.disable_all_colors()  
9 -  
10 -  
11 -def enable_all_colors():  
12 - """Enable colors."""  
13 - ANSICodeMapping.enable_all_colors()  
14 -  
15 -  
16 -def disable_if_no_tty():  
17 - """Disable all colors if there is no TTY available.  
18 -  
19 - :return: True if colors are disabled, False if stderr or stdout is a TTY.  
20 - :rtype: bool  
21 - """  
22 - return ANSICodeMapping.disable_if_no_tty()  
23 -  
24 -  
25 -def is_enabled():  
26 - """Are colors enabled."""  
27 - return not ANSICodeMapping.DISABLE_COLORS  
28 -  
29 -  
30 -def set_light_background():  
31 - """Choose dark colors for all 'auto'-prefixed codes for readability on light backgrounds."""  
32 - ANSICodeMapping.set_light_background()  
33 -  
34 -  
35 -def set_dark_background():  
36 - """Choose dark colors for all 'auto'-prefixed codes for readability on light backgrounds."""  
37 - ANSICodeMapping.set_dark_background()  
38 -  
39 -  
40 -def is_light():  
41 - """Are background colors for light backgrounds."""  
42 - return ANSICodeMapping.LIGHT_BACKGROUND  
oletools/thirdparty/colorclass/windows.py deleted
1 -"""Windows console screen buffer handlers."""  
2 -  
3 -from __future__ import print_function  
4 -  
5 -import atexit  
6 -import ctypes  
7 -import re  
8 -import sys  
9 -  
10 -from colorclass.codes import ANSICodeMapping, BASE_CODES  
11 -from colorclass.core import RE_SPLIT  
12 -  
13 -ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004  
14 -INVALID_HANDLE_VALUE = -1  
15 -IS_WINDOWS = sys.platform == 'win32'  
16 -RE_NUMBER_SEARCH = re.compile(r'\033\[([\d;]+)m')  
17 -STD_ERROR_HANDLE = -12  
18 -STD_OUTPUT_HANDLE = -11  
19 -WINDOWS_CODES = {  
20 - '/all': -33, '/fg': -39, '/bg': -49,  
21 -  
22 - 'black': 0, 'red': 4, 'green': 2, 'yellow': 6, 'blue': 1, 'magenta': 5, 'cyan': 3, 'white': 7,  
23 -  
24 - 'bgblack': -8, 'bgred': 64, 'bggreen': 32, 'bgyellow': 96, 'bgblue': 16, 'bgmagenta': 80, 'bgcyan': 48,  
25 - 'bgwhite': 112,  
26 -  
27 - 'hiblack': 8, 'hired': 12, 'higreen': 10, 'hiyellow': 14, 'hiblue': 9, 'himagenta': 13, 'hicyan': 11, 'hiwhite': 15,  
28 -  
29 - 'hibgblack': 128, 'hibgred': 192, 'hibggreen': 160, 'hibgyellow': 224, 'hibgblue': 144, 'hibgmagenta': 208,  
30 - 'hibgcyan': 176, 'hibgwhite': 240,  
31 -  
32 - '/black': -39, '/red': -39, '/green': -39, '/yellow': -39, '/blue': -39, '/magenta': -39, '/cyan': -39,  
33 - '/white': -39, '/hiblack': -39, '/hired': -39, '/higreen': -39, '/hiyellow': -39, '/hiblue': -39, '/himagenta': -39,  
34 - '/hicyan': -39, '/hiwhite': -39,  
35 -  
36 - '/bgblack': -49, '/bgred': -49, '/bggreen': -49, '/bgyellow': -49, '/bgblue': -49, '/bgmagenta': -49,  
37 - '/bgcyan': -49, '/bgwhite': -49, '/hibgblack': -49, '/hibgred': -49, '/hibggreen': -49, '/hibgyellow': -49,  
38 - '/hibgblue': -49, '/hibgmagenta': -49, '/hibgcyan': -49, '/hibgwhite': -49,  
39 -}  
40 -  
41 -  
42 -class COORD(ctypes.Structure):  
43 - """COORD structure. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119."""  
44 -  
45 - _fields_ = [  
46 - ('X', ctypes.c_short),  
47 - ('Y', ctypes.c_short),  
48 - ]  
49 -  
50 -  
51 -class SmallRECT(ctypes.Structure):  
52 - """SMALL_RECT structure. http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311."""  
53 -  
54 - _fields_ = [  
55 - ('Left', ctypes.c_short),  
56 - ('Top', ctypes.c_short),  
57 - ('Right', ctypes.c_short),  
58 - ('Bottom', ctypes.c_short),  
59 - ]  
60 -  
61 -  
62 -class ConsoleScreenBufferInfo(ctypes.Structure):  
63 - """CONSOLE_SCREEN_BUFFER_INFO structure. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093."""  
64 -  
65 - _fields_ = [  
66 - ('dwSize', COORD),  
67 - ('dwCursorPosition', COORD),  
68 - ('wAttributes', ctypes.c_ushort),  
69 - ('srWindow', SmallRECT),  
70 - ('dwMaximumWindowSize', COORD)  
71 - ]  
72 -  
73 -  
74 -def init_kernel32(kernel32=None):  
75 - """Load a unique instance of WinDLL into memory, set arg/return types, and get stdout/err handles.  
76 -  
77 - 1. Since we are setting DLL function argument types and return types, we need to maintain our own instance of  
78 - kernel32 to prevent overriding (or being overwritten by) user's own changes to ctypes.windll.kernel32.  
79 - 2. While we're doing all this we might as well get the handles to STDOUT and STDERR streams.  
80 - 3. If either stream has already been replaced set return value to INVALID_HANDLE_VALUE to indicate it shouldn't be  
81 - replaced.  
82 -  
83 - :raise AttributeError: When called on a non-Windows platform.  
84 -  
85 - :param kernel32: Optional mock kernel32 object. For testing.  
86 -  
87 - :return: Loaded kernel32 instance, stderr handle (int), stdout handle (int).  
88 - :rtype: tuple  
89 - """  
90 - if not kernel32:  
91 - kernel32 = ctypes.LibraryLoader(ctypes.WinDLL).kernel32 # Load our own instance. Unique memory address.  
92 - kernel32.GetStdHandle.argtypes = [ctypes.c_ulong]  
93 - kernel32.GetStdHandle.restype = ctypes.c_void_p  
94 - kernel32.GetConsoleScreenBufferInfo.argtypes = [  
95 - ctypes.c_void_p,  
96 - ctypes.POINTER(ConsoleScreenBufferInfo),  
97 - ]  
98 - kernel32.GetConsoleScreenBufferInfo.restype = ctypes.c_long  
99 -  
100 - # Get handles.  
101 - if hasattr(sys.stderr, '_original_stream'):  
102 - stderr = INVALID_HANDLE_VALUE  
103 - else:  
104 - stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE)  
105 - if hasattr(sys.stdout, '_original_stream'):  
106 - stdout = INVALID_HANDLE_VALUE  
107 - else:  
108 - stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)  
109 -  
110 - return kernel32, stderr, stdout  
111 -  
112 -  
113 -def get_console_info(kernel32, handle):  
114 - """Get information about this current console window.  
115 -  
116 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231  
117 - https://code.google.com/p/colorama/issues/detail?id=47  
118 - https://bitbucket.org/pytest-dev/py/src/4617fe46/py/_io/terminalwriter.py  
119 -  
120 - Windows 10 Insider since around February 2016 finally introduced support for ANSI colors. No need to replace stdout  
121 - and stderr streams to intercept colors and issue multiple SetConsoleTextAttribute() calls for these consoles.  
122 -  
123 - :raise OSError: When GetConsoleScreenBufferInfo or GetConsoleMode API calls fail.  
124 -  
125 - :param ctypes.windll.kernel32 kernel32: Loaded kernel32 instance.  
126 - :param int handle: stderr or stdout handle.  
127 -  
128 - :return: Foreground and background colors (integers) as well as native ANSI support (bool).  
129 - :rtype: tuple  
130 - """  
131 - # Query Win32 API.  
132 - csbi = ConsoleScreenBufferInfo() # Populated by GetConsoleScreenBufferInfo.  
133 - lpcsbi = ctypes.byref(csbi)  
134 - dword = ctypes.c_ulong() # Populated by GetConsoleMode.  
135 - lpdword = ctypes.byref(dword)  
136 - if not kernel32.GetConsoleScreenBufferInfo(handle, lpcsbi) or not kernel32.GetConsoleMode(handle, lpdword):  
137 - raise ctypes.WinError()  
138 -  
139 - # Parse data.  
140 - # buffer_width = int(csbi.dwSize.X - 1)  
141 - # buffer_height = int(csbi.dwSize.Y)  
142 - # terminal_width = int(csbi.srWindow.Right - csbi.srWindow.Left)  
143 - # terminal_height = int(csbi.srWindow.Bottom - csbi.srWindow.Top)  
144 - fg_color = csbi.wAttributes % 16  
145 - bg_color = csbi.wAttributes & 240  
146 - native_ansi = bool(dword.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING)  
147 -  
148 - return fg_color, bg_color, native_ansi  
149 -  
150 -  
151 -def bg_color_native_ansi(kernel32, stderr, stdout):  
152 - """Get background color and if console supports ANSI colors natively for both streams.  
153 -  
154 - :param ctypes.windll.kernel32 kernel32: Loaded kernel32 instance.  
155 - :param int stderr: stderr handle.  
156 - :param int stdout: stdout handle.  
157 -  
158 - :return: Background color (int) and native ANSI support (bool).  
159 - :rtype: tuple  
160 - """  
161 - try:  
162 - if stderr == INVALID_HANDLE_VALUE:  
163 - raise OSError  
164 - bg_color, native_ansi = get_console_info(kernel32, stderr)[1:]  
165 - except OSError:  
166 - try:  
167 - if stdout == INVALID_HANDLE_VALUE:  
168 - raise OSError  
169 - bg_color, native_ansi = get_console_info(kernel32, stdout)[1:]  
170 - except OSError:  
171 - bg_color, native_ansi = WINDOWS_CODES['black'], False  
172 - return bg_color, native_ansi  
173 -  
174 -  
175 -class WindowsStream(object):  
176 - """Replacement stream which overrides sys.stdout or sys.stderr. When writing or printing, ANSI codes are converted.  
177 -  
178 - ANSI (Linux/Unix) color codes are converted into win32 system calls, changing the next character's color before  
179 - printing it. Resources referenced:  
180 - https://github.com/tartley/colorama  
181 - http://www.cplusplus.com/articles/2ywTURfi/  
182 - http://thomasfischer.biz/python-and-windows-terminal-colors/  
183 - http://stackoverflow.com/questions/17125440/c-win32-console-color  
184 - http://www.tysos.org/svn/trunk/mono/corlib/System/WindowsConsoleDriver.cs  
185 - http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python  
186 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms682088#_win32_character_attributes  
187 -  
188 - :cvar list ALL_BG_CODES: List of bg Windows codes. Used to determine if requested color is foreground or background.  
189 - :cvar dict COMPILED_CODES: Translation dict. Keys are ANSI codes (values of BASE_CODES), values are Windows codes.  
190 - :ivar int default_fg: Foreground Windows color code at the time of instantiation.  
191 - :ivar int default_bg: Background Windows color code at the time of instantiation.  
192 - """  
193 -  
194 - ALL_BG_CODES = [v for k, v in WINDOWS_CODES.items() if k.startswith('bg') or k.startswith('hibg')]  
195 - COMPILED_CODES = dict((v, WINDOWS_CODES[k]) for k, v in BASE_CODES.items() if k in WINDOWS_CODES)  
196 -  
197 - def __init__(self, kernel32, stream_handle, original_stream):  
198 - """Constructor.  
199 -  
200 - :param ctypes.windll.kernel32 kernel32: Loaded kernel32 instance.  
201 - :param int stream_handle: stderr or stdout handle.  
202 - :param original_stream: sys.stderr or sys.stdout before being overridden by this class' instance.  
203 - """  
204 - self._kernel32 = kernel32  
205 - self._stream_handle = stream_handle  
206 - self._original_stream = original_stream  
207 - self.default_fg, self.default_bg = self.colors  
208 -  
209 - def __getattr__(self, item):  
210 - """If an attribute/function/etc is not defined in this function, retrieve the one from the original stream.  
211 -  
212 - Fixes ipython arrow key presses.  
213 - """  
214 - return getattr(self._original_stream, item)  
215 -  
216 - @property  
217 - def colors(self):  
218 - """Return the current foreground and background colors."""  
219 - try:  
220 - return get_console_info(self._kernel32, self._stream_handle)[:2]  
221 - except OSError:  
222 - return WINDOWS_CODES['white'], WINDOWS_CODES['black']  
223 -  
224 - @colors.setter  
225 - def colors(self, color_code):  
226 - """Change the foreground and background colors for subsequently printed characters.  
227 -  
228 - None resets colors to their original values (when class was instantiated).  
229 -  
230 - Since setting a color requires including both foreground and background codes (merged), setting just the  
231 - foreground color resets the background color to black, and vice versa.  
232 -  
233 - This function first gets the current background and foreground colors, merges in the requested color code, and  
234 - sets the result.  
235 -  
236 - However if we need to remove just the foreground color but leave the background color the same (or vice versa)  
237 - such as when {/red} is used, we must merge the default foreground color with the current background color. This  
238 - is the reason for those negative values.  
239 -  
240 - :param int color_code: Color code from WINDOWS_CODES.  
241 - """  
242 - if color_code is None:  
243 - color_code = WINDOWS_CODES['/all']  
244 -  
245 - # Get current color code.  
246 - current_fg, current_bg = self.colors  
247 -  
248 - # Handle special negative codes. Also determine the final color code.  
249 - if color_code == WINDOWS_CODES['/fg']:  
250 - final_color_code = self.default_fg | current_bg # Reset the foreground only.  
251 - elif color_code == WINDOWS_CODES['/bg']:  
252 - final_color_code = current_fg | self.default_bg # Reset the background only.  
253 - elif color_code == WINDOWS_CODES['/all']:  
254 - final_color_code = self.default_fg | self.default_bg # Reset both.  
255 - elif color_code == WINDOWS_CODES['bgblack']:  
256 - final_color_code = current_fg # Black background.  
257 - else:  
258 - new_is_bg = color_code in self.ALL_BG_CODES  
259 - final_color_code = color_code | (current_fg if new_is_bg else current_bg)  
260 -  
261 - # Set new code.  
262 - self._kernel32.SetConsoleTextAttribute(self._stream_handle, final_color_code)  
263 -  
264 - def write(self, p_str):  
265 - """Write to stream.  
266 -  
267 - :param str p_str: string to print.  
268 - """  
269 - for segment in RE_SPLIT.split(p_str):  
270 - if not segment:  
271 - # Empty string. p_str probably starts with colors so the first item is always ''.  
272 - continue  
273 - if not RE_SPLIT.match(segment):  
274 - # No color codes, print regular text.  
275 - print(segment, file=self._original_stream, end='')  
276 - self._original_stream.flush()  
277 - continue  
278 - for color_code in (int(c) for c in RE_NUMBER_SEARCH.findall(segment)[0].split(';')):  
279 - if color_code in self.COMPILED_CODES:  
280 - self.colors = self.COMPILED_CODES[color_code]  
281 -  
282 -  
283 -class Windows(object):  
284 - """Enable and disable Windows support for ANSI color character codes.  
285 -  
286 - Call static method Windows.enable() to enable color support for the remainder of the process' lifetime.  
287 -  
288 - This class is also a context manager. You can do this:  
289 - with Windows():  
290 - print(Color('{autored}Test{/autored}'))  
291 -  
292 - Or this:  
293 - with Windows(auto_colors=True):  
294 - print(Color('{autored}Test{/autored}'))  
295 - """  
296 -  
297 - @classmethod  
298 - def disable(cls):  
299 - """Restore sys.stderr and sys.stdout to their original objects. Resets colors to their original values.  
300 -  
301 - :return: If streams restored successfully.  
302 - :rtype: bool  
303 - """  
304 - # Skip if not on Windows.  
305 - if not IS_WINDOWS:  
306 - return False  
307 -  
308 - # Restore default colors.  
309 - if hasattr(sys.stderr, '_original_stream'):  
310 - getattr(sys, 'stderr').color = None  
311 - if hasattr(sys.stdout, '_original_stream'):  
312 - getattr(sys, 'stdout').color = None  
313 -  
314 - # Restore original streams.  
315 - changed = False  
316 - if hasattr(sys.stderr, '_original_stream'):  
317 - changed = True  
318 - sys.stderr = getattr(sys.stderr, '_original_stream')  
319 - if hasattr(sys.stdout, '_original_stream'):  
320 - changed = True  
321 - sys.stdout = getattr(sys.stdout, '_original_stream')  
322 -  
323 - return changed  
324 -  
325 - @staticmethod  
326 - def is_enabled():  
327 - """Return True if either stderr or stdout has colors enabled."""  
328 - return hasattr(sys.stderr, '_original_stream') or hasattr(sys.stdout, '_original_stream')  
329 -  
330 - @classmethod  
331 - def enable(cls, auto_colors=False, reset_atexit=False):  
332 - """Enable color text with print() or sys.stdout.write() (stderr too).  
333 -  
334 - :param bool auto_colors: Automatically selects dark or light colors based on current terminal's background  
335 - color. Only works with {autored} and related tags.  
336 - :param bool reset_atexit: Resets original colors upon Python exit (in case you forget to reset it yourself with  
337 - a closing tag). Does nothing on native ANSI consoles.  
338 -  
339 - :return: If streams replaced successfully.  
340 - :rtype: bool  
341 - """  
342 - if not IS_WINDOWS:  
343 - return False # Windows only.  
344 -  
345 - # Get values from init_kernel32().  
346 - kernel32, stderr, stdout = init_kernel32()  
347 - if stderr == INVALID_HANDLE_VALUE and stdout == INVALID_HANDLE_VALUE:  
348 - return False # No valid handles, nothing to do.  
349 -  
350 - # Get console info.  
351 - bg_color, native_ansi = bg_color_native_ansi(kernel32, stderr, stdout)  
352 -  
353 - # Set auto colors:  
354 - if auto_colors:  
355 - if bg_color in (112, 96, 240, 176, 224, 208, 160):  
356 - ANSICodeMapping.set_light_background()  
357 - else:  
358 - ANSICodeMapping.set_dark_background()  
359 -  
360 - # Don't replace streams if ANSI codes are natively supported.  
361 - if native_ansi:  
362 - return False  
363 -  
364 - # Reset on exit if requested.  
365 - if reset_atexit:  
366 - atexit.register(cls.disable)  
367 -  
368 - # Overwrite stream references.  
369 - if stderr != INVALID_HANDLE_VALUE:  
370 - sys.stderr.flush()  
371 - sys.stderr = WindowsStream(kernel32, stderr, sys.stderr)  
372 - if stdout != INVALID_HANDLE_VALUE:  
373 - sys.stdout.flush()  
374 - sys.stdout = WindowsStream(kernel32, stdout, sys.stdout)  
375 -  
376 - return True  
377 -  
378 - def __init__(self, auto_colors=False):  
379 - """Constructor."""  
380 - self.auto_colors = auto_colors  
381 -  
382 - def __enter__(self):  
383 - """Context manager, enables colors on Windows."""  
384 - self.enable(auto_colors=self.auto_colors)  
385 -  
386 - def __exit__(self, *_):  
387 - """Context manager, disabled colors on Windows."""  
388 - self.disable()  
oletools/thirdparty/tablestream/tablestream.py
@@ -19,7 +19,7 @@ License: BSD, see source code or documentation @@ -19,7 +19,7 @@ License: BSD, see source code or documentation
19 19
20 #=== LICENSE ================================================================== 20 #=== LICENSE ==================================================================
21 21
22 -# tablestream is copyright (c) 2015-2016 Philippe Lagadec (http://www.decalage.info) 22 +# tablestream is copyright (c) 2015-2018 Philippe Lagadec (http://www.decalage.info)
23 # All rights reserved. 23 # All rights reserved.
24 # 24 #
25 # Redistribution and use in source and binary forms, with or without modification, 25 # Redistribution and use in source and binary forms, with or without modification,
@@ -54,8 +54,9 @@ from __future__ import print_function @@ -54,8 +54,9 @@ from __future__ import print_function
54 # 2016-07-31 v0.06 PL: - handle newline characters properly in each cell 54 # 2016-07-31 v0.06 PL: - handle newline characters properly in each cell
55 # 2016-08-28 v0.07 PL: - support for both Python 2.6+ and 3.x 55 # 2016-08-28 v0.07 PL: - support for both Python 2.6+ and 3.x
56 # - all cells are converted to unicode 56 # - all cells are converted to unicode
  57 +# 2018-09-22 v0.08 PL: - removed mention to oletools' thirdparty folder
57 58
58 -__version__ = '0.07' 59 +__version__ = '0.08'
59 60
60 #------------------------------------------------------------------------------ 61 #------------------------------------------------------------------------------
61 # TODO: 62 # TODO:
@@ -70,15 +71,6 @@ __version__ = &#39;0.07&#39; @@ -70,15 +71,6 @@ __version__ = &#39;0.07&#39;
70 import textwrap 71 import textwrap
71 import sys, os 72 import sys, os
72 73
73 -# add the thirdparty subfolder to sys.path (absolute+normalized path):  
74 -_thismodule_dir = os.path.normpath(os.path.abspath(os.path.dirname(__file__)))  
75 -# print('_thismodule_dir = %r' % _thismodule_dir)  
76 -# assumption: this module is in a subfolder of thirdparty:  
77 -_thirdparty_dir = os.path.normpath(os.path.join(_thismodule_dir, '..'))  
78 -# print('_thirdparty_dir = %r' % _thirdparty_dir)  
79 -if not _thirdparty_dir in sys.path:  
80 - sys.path.insert(0, _thirdparty_dir)  
81 -  
82 import colorclass 74 import colorclass
83 75
84 # On Windows, colorclass needs to be enabled: 76 # On Windows, colorclass needs to be enabled:
setup.py
@@ -26,6 +26,7 @@ to install this package. @@ -26,6 +26,7 @@ to install this package.
26 # 2018-03-19 v0.52.3 PL: - added install_requires, removed thirdparty.pyparsing 26 # 2018-03-19 v0.52.3 PL: - added install_requires, removed thirdparty.pyparsing
27 # 2018-09-11 v0.54 PL: - olefile is now a dependency 27 # 2018-09-11 v0.54 PL: - olefile is now a dependency
28 # 2018-09-15 PL: - easygui is now a dependency 28 # 2018-09-15 PL: - easygui is now a dependency
  29 +# 2018-09-22 PL: - colorclass is now a dependency
29 30
30 #--- TODO --------------------------------------------------------------------- 31 #--- TODO ---------------------------------------------------------------------
31 32
@@ -85,7 +86,6 @@ packages=[ @@ -85,7 +86,6 @@ packages=[
85 'oletools.thirdparty.prettytable', 86 'oletools.thirdparty.prettytable',
86 'oletools.thirdparty.xglob', 87 'oletools.thirdparty.xglob',
87 'oletools.thirdparty.DridexUrlDecoder', 88 'oletools.thirdparty.DridexUrlDecoder',
88 - 'oletools.thirdparty.colorclass',  
89 'oletools.thirdparty.tablestream', 89 'oletools.thirdparty.tablestream',
90 'oletools.thirdparty.zipfile27', 90 'oletools.thirdparty.zipfile27',
91 ] 91 ]
@@ -175,9 +175,6 @@ package_data={ @@ -175,9 +175,6 @@ package_data={
175 'oletools.thirdparty.DridexUrlDecoder': [ 175 'oletools.thirdparty.DridexUrlDecoder': [
176 'LICENSE.txt', 176 'LICENSE.txt',
177 ], 177 ],
178 - 'oletools.thirdparty.colorclass': [  
179 - 'LICENSE.txt',  
180 - ],  
181 'oletools.thirdparty.zipfile27': [ 178 'oletools.thirdparty.zipfile27': [
182 'LICENSE.txt', 179 'LICENSE.txt',
183 ], 180 ],
@@ -318,6 +315,7 @@ def main(): @@ -318,6 +315,7 @@ def main():
318 "pyparsing>=2.2.0", 315 "pyparsing>=2.2.0",
319 "olefile>=0.46", 316 "olefile>=0.46",
320 "easygui", 317 "easygui",
  318 + 'colorclass',
321 ], 319 ],
322 ) 320 )
323 321