Line | Count | Source (jump to first uncovered line) |
1 | | /* options.cpp -- |
2 | | |
3 | | This file is part of the UPX executable compressor. |
4 | | |
5 | | Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer |
6 | | Copyright (C) 1996-2025 Laszlo Molnar |
7 | | All Rights Reserved. |
8 | | |
9 | | UPX and the UCL library are free software; you can redistribute them |
10 | | and/or modify them under the terms of the GNU General Public License as |
11 | | published by the Free Software Foundation; either version 2 of |
12 | | the License, or (at your option) any later version. |
13 | | |
14 | | This program is distributed in the hope that it will be useful, |
15 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | GNU General Public License for more details. |
18 | | |
19 | | You should have received a copy of the GNU General Public License |
20 | | along with this program; see the file COPYING. |
21 | | If not, write to the Free Software Foundation, Inc., |
22 | | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
23 | | |
24 | | Markus F.X.J. Oberhumer Laszlo Molnar |
25 | | <markus@oberhumer.com> <ezerotven+github@gmail.com> |
26 | | */ |
27 | | |
28 | | #include "conf.h" |
29 | | |
30 | | static Options global_options; |
31 | | // also see class PackMaster for per-file local options |
32 | | Options *opt = &global_options; |
33 | | |
34 | | #if WITH_THREADS |
35 | | std::mutex opt_lock_mutex; // for locking "opt" |
36 | | #endif |
37 | | |
38 | | /************************************************************************* |
39 | | // reset |
40 | | **************************************************************************/ |
41 | | |
42 | 70.8k | void Options::reset() noexcept { |
43 | 70.8k | #define opt ERROR_DO_NOT_USE_opt // self-protect against using the wrong variable |
44 | 70.8k | Options *const o = this; |
45 | 70.8k | mem_clear(o); |
46 | 70.8k | o->crp.reset(); |
47 | | |
48 | 70.8k | o->cmd = CMD_NONE; |
49 | 70.8k | o->method = M_NONE; |
50 | 70.8k | o->level = -1; |
51 | 70.8k | o->filter = FT_NONE; |
52 | | |
53 | 70.8k | o->backup = -1; |
54 | 70.8k | o->overlay = -1; |
55 | 70.8k | o->preserve_mode = true; |
56 | 70.8k | o->preserve_ownership = true; |
57 | 70.8k | o->preserve_timestamp = true; |
58 | 70.8k | o->verbose = 2; |
59 | | |
60 | 70.8k | o->console = CON_FILE; |
61 | | #if (ACC_OS_DOS32) && defined(__DJGPP__) |
62 | | o->console = CON_INIT; |
63 | | #elif (USE_SCREEN_WIN32) |
64 | | o->console = CON_INIT; |
65 | | #elif 1 && defined(__linux__) |
66 | | o->console = CON_INIT; |
67 | 70.8k | #endif |
68 | | // support NO_COLOR, see https://no-color.org/ |
69 | | // "... when present and not an empty string (regardless of its value)" |
70 | 70.8k | const char *e = upx_getenv("NO_COLOR"); |
71 | 70.8k | if (e && e[0]) |
72 | 0 | o->console = CON_FILE; |
73 | | |
74 | | // options for various executable formats |
75 | | |
76 | 70.8k | o->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX |
77 | | |
78 | 70.8k | o->win32_pe.compress_exports = 1; |
79 | 70.8k | o->win32_pe.compress_icons = 2; |
80 | 70.8k | o->win32_pe.compress_resources = -1; |
81 | 1.84M | for (size_t i = 0; i < TABLESIZE(o->win32_pe.compress_rt); i++) |
82 | 1.77M | o->win32_pe.compress_rt[i] = -1; |
83 | 70.8k | o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST |
84 | 70.8k | o->win32_pe.strip_relocs = -1; |
85 | 70.8k | o->win32_pe.keep_resource = ""; |
86 | 70.8k | #undef opt |
87 | 70.8k | } |
88 | | |
89 | | /************************************************************************* |
90 | | // doctest checks |
91 | | **************************************************************************/ |
92 | | |
93 | 7.08k | TEST_CASE("Options::reset") { |
94 | 7.08k | #define opt ERROR_DO_NOT_USE_opt // self-protect against using the wrong variable |
95 | 7.08k | COMPILE_TIME_ASSERT(std::is_standard_layout<Options>::value) |
96 | 7.08k | COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<Options>::value) |
97 | 7.08k | COMPILE_TIME_ASSERT(std::is_trivially_copyable<Options>::value) |
98 | | |
99 | 7.08k | Options local_options; |
100 | 7.08k | Options *const o = &local_options; |
101 | 7.08k | o->reset(); |
102 | 7.08k | CHECK(o->o_unix.osabi0 == 3); |
103 | 7.08k | static_assert(TABLESIZE(o->win32_pe.compress_rt) == 25); // 25 == RT_LAST |
104 | 7.08k | CHECK(o->win32_pe.compress_exports); |
105 | 7.08k | CHECK(o->win32_pe.compress_icons); |
106 | 7.08k | CHECK(o->win32_pe.strip_relocs); |
107 | | // issue 728 |
108 | 7.08k | CHECK(o->win32_pe.compress_resources); |
109 | 177k | for (size_t i = 0; i < 24; i++) |
110 | 170k | CHECK(o->win32_pe.compress_rt[i]); |
111 | 7.08k | CHECK(!o->win32_pe.compress_rt[24]); // 24 == RT_MANIFEST |
112 | 7.08k | #undef opt |
113 | 7.08k | } |
114 | | |
115 | | template <size_t N> |
116 | 56.6k | static inline void test_options(const char *(&a)[N]) { |
117 | 56.6k | (void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a)); |
118 | 56.6k | } options.cpp:void test_options<4ul>(char const* (&) [4ul]) Line | Count | Source | 116 | 42.5k | static inline void test_options(const char *(&a)[N]) { | 117 | 42.5k | (void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a)); | 118 | 42.5k | } |
options.cpp:void test_options<5ul>(char const* (&) [5ul]) Line | Count | Source | 116 | 14.1k | static inline void test_options(const char *(&a)[N]) { | 117 | 14.1k | (void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a)); | 118 | 14.1k | } |
|
119 | | |
120 | 56.6k | TEST_CASE("getopt") { |
121 | | #if WITH_THREADS |
122 | | std::lock_guard<std::mutex> lock(opt_lock_mutex); |
123 | | #endif |
124 | 56.6k | Options *const saved_opt = opt; |
125 | 56.6k | Options local_options; |
126 | 56.6k | opt = &local_options; |
127 | 56.6k | opt->reset(); |
128 | 56.6k | opt->debug.getopt_throw_instead_of_exit = true; |
129 | 56.6k | static const char a0[] = "<argv0>"; |
130 | | |
131 | 56.6k | SUBCASE("issue 587") { |
132 | 7.08k | const char *a[] = {a0, "--brute", "--lzma", nullptr}; |
133 | 7.08k | test_options(a); |
134 | 7.08k | CHECK(opt->all_methods); |
135 | 7.08k | CHECK(opt->all_methods_use_lzma == 1); |
136 | 7.08k | } |
137 | 56.6k | SUBCASE("issue 587") { |
138 | 7.08k | const char *a[] = {a0, "--lzma", "--brute", nullptr}; |
139 | 7.08k | test_options(a); |
140 | 7.08k | CHECK(opt->all_methods); |
141 | 7.08k | CHECK(opt->all_methods_use_lzma == 1); |
142 | 7.08k | } |
143 | 56.6k | SUBCASE("issue 587") { |
144 | 7.08k | const char *a[] = {a0, "--brute", "--no-lzma", nullptr}; |
145 | 7.08k | test_options(a); |
146 | 7.08k | CHECK(opt->all_methods); |
147 | 7.08k | CHECK(opt->all_methods_use_lzma == -1); |
148 | 7.08k | } |
149 | 56.6k | SUBCASE("issue 587") { |
150 | 7.08k | const char *a[] = {a0, "--no-lzma", "--brute", nullptr}; |
151 | 7.08k | test_options(a); |
152 | 7.08k | CHECK(opt->all_methods); |
153 | 7.08k | CHECK(opt->all_methods_use_lzma == -1); |
154 | 7.08k | } |
155 | 56.6k | SUBCASE("issue 587") { |
156 | 7.08k | const char *a[] = {a0, "--no-lzma", "--lzma", nullptr}; |
157 | 7.08k | test_options(a); |
158 | 7.08k | CHECK(!opt->all_methods); |
159 | 7.08k | CHECK(opt->all_methods_use_lzma == 1); |
160 | 7.08k | CHECK(opt->method == M_LZMA); |
161 | 7.08k | } |
162 | 56.6k | SUBCASE("issue 587") { |
163 | 7.08k | const char *a[] = {a0, "--no-lzma", "--lzma", "--brute", nullptr}; |
164 | 7.08k | test_options(a); |
165 | 7.08k | CHECK(opt->all_methods); |
166 | 7.08k | CHECK(opt->all_methods_use_lzma == 1); |
167 | 7.08k | CHECK(opt->method == -1); |
168 | 7.08k | } |
169 | 56.6k | SUBCASE("issue 587") { |
170 | 7.08k | const char *a[] = {a0, "--lzma", "--no-lzma", nullptr}; |
171 | 7.08k | test_options(a); |
172 | 7.08k | CHECK(!opt->all_methods); |
173 | 7.08k | CHECK(opt->all_methods_use_lzma == -1); |
174 | 7.08k | CHECK(opt->method == -1); |
175 | 7.08k | } |
176 | 56.6k | SUBCASE("issue 587") { |
177 | 7.08k | const char *a[] = {a0, "--lzma", "--no-lzma", "--brute", nullptr}; |
178 | 7.08k | test_options(a); |
179 | 7.08k | CHECK(opt->all_methods); |
180 | 7.08k | CHECK(opt->all_methods_use_lzma == -1); |
181 | 7.08k | CHECK(opt->method == -1); |
182 | 7.08k | } |
183 | | |
184 | 56.6k | opt = saved_opt; |
185 | 56.6k | } |
186 | | |
187 | | /* vim:set ts=4 sw=4 et: */ |