blob: f84df8e2be68a8640ac4adf0ee6fe424e53f6629 [file] [log] [blame]
Mike Frysinger50e31fa2018-01-19 18:59:49 -05001/* Copyright 2018 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Test util.[ch] module code using gtest.
6 */
Mike Frysinger32c39922018-01-17 17:09:54 -05007
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/stat.h>
12#include <unistd.h>
13
14#include <gtest/gtest.h>
15
Mike Frysinger70b15b82020-09-03 18:10:57 -040016#include "bpf.h"
Mike Frysinger32c39922018-01-17 17:09:54 -050017#include "util.h"
18
Mattias Nisslerb35f2c12020-02-07 13:37:36 +010019namespace {
20
21std::string dump_env(const char *const *env) {
22 std::string result;
23 for (; *env; ++env) {
24 result += *env;
25 result += "\n";
26 }
27
28 return result;
29}
30
31} // namespace
32
Mike Frysinger32c39922018-01-17 17:09:54 -050033// Sanity check for the strip func.
34TEST(strip, basic) {
35 char str[] = " foo\t";
36 ASSERT_EQ("foo", std::string(strip(str)));
37}
38
39// Make sure we don't crash with various "null"-like inputs.
40TEST(tokenize, null_stringp) {
41 ASSERT_EQ(nullptr, tokenize(nullptr, nullptr));
42 ASSERT_EQ(nullptr, tokenize(nullptr, ""));
43 ASSERT_EQ(nullptr, tokenize(nullptr, ","));
44
45 char *p = nullptr;
46 ASSERT_EQ(nullptr, tokenize(&p, nullptr));
47}
48
49// Make sure we don't crash with various "null"-like inputs.
50TEST(tokenize, null_delim) {
51 char str[] = "a,b,c";
52 char *p = str;
53 ASSERT_EQ(str, tokenize(&p, nullptr));
54 ASSERT_EQ(nullptr, p);
55 ASSERT_EQ(str, std::string("a,b,c"));
56
57 p = str;
58 ASSERT_EQ(str, tokenize(&p, ""));
59 ASSERT_EQ(nullptr, p);
60 ASSERT_EQ(str, std::string("a,b,c"));
61}
62
63// Sanity check for the tokenize func.
64TEST(tokenize, basic) {
65 char str[] = "a,b,c";
66 char *p = str;
67 ASSERT_EQ("a", std::string(tokenize(&p, ",")));
68 ASSERT_EQ("b", std::string(tokenize(&p, ",")));
69 ASSERT_EQ("c", std::string(tokenize(&p, ",")));
70 ASSERT_EQ(nullptr, p);
71 ASSERT_EQ(nullptr, tokenize(&p, ","));
72}
Mike Frysingerb4c7e772018-01-17 17:40:15 -050073
74// Check edge case with an empty string.
75TEST(tokenize, empty_string) {
76 char str[] = "";
77 char *p = str;
78 ASSERT_EQ("", std::string(tokenize(&p, ",")));
79 ASSERT_EQ(nullptr, p);
80 ASSERT_EQ(nullptr, tokenize(&p, ","));
81}
82
83// Check behavior with empty tokens at the start/middle/end.
84TEST(tokenize, empty_tokens) {
85 char str[] = ",,a,b,,,c,,";
86 char *p = str;
87 ASSERT_EQ("", std::string(tokenize(&p, ",")));
88 ASSERT_EQ("", std::string(tokenize(&p, ",")));
89 ASSERT_EQ("a", std::string(tokenize(&p, ",")));
90 ASSERT_EQ("b", std::string(tokenize(&p, ",")));
91 ASSERT_EQ("", std::string(tokenize(&p, ",")));
92 ASSERT_EQ("", std::string(tokenize(&p, ",")));
93 ASSERT_EQ("c", std::string(tokenize(&p, ",")));
94 ASSERT_EQ("", std::string(tokenize(&p, ",")));
95 ASSERT_EQ("", std::string(tokenize(&p, ",")));
96 ASSERT_EQ(nullptr, p);
97 ASSERT_EQ(nullptr, tokenize(&p, ","));
98}
Mattias Nisslerb35f2c12020-02-07 13:37:36 +010099
100// Check environment manipulation functions.
101TEST(environment, copy_and_modify) {
102 minijail_free_env(nullptr);
103
104 char **env = minijail_copy_env(nullptr);
105 EXPECT_EQ("", dump_env(env));
106 minijail_free_env(env);
107
108 const char *const kConstEnv[] = {
109 "val1=1",
110 "val2=2",
111 "dup=1",
112 "dup=2",
113 "empty=",
114 nullptr,
115 };
116
117 // libc unfortunately uses char* const[] as the type for the environment, and
118 // we match that. It's actually missing a const-ness of the chars making up
119 // the environment strings, but we need that to initialize the |kEnv|
120 // constant. Hence, do a cast here to force things into alignment...
121 char* const* kEnv = const_cast<char* const*>(kConstEnv);
122
123 env = minijail_copy_env(kEnv);
124 EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
125 minijail_free_env(env);
126
127 env = minijail_copy_env(kEnv);
128 EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
129
130 EXPECT_EQ(EINVAL, minijail_setenv(nullptr, "val1", "3", 1));
131 char **env_ret = nullptr;
132 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "val1", "3", 1));
133
134 env_ret = env;
135 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, nullptr, "3", 1));
136 EXPECT_EQ(env, env_ret);
137 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "", "3", 1));
138 EXPECT_EQ(env, env_ret);
139 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "", nullptr, 1));
140 EXPECT_EQ(env, env_ret);
141
142 EXPECT_EQ(0, minijail_setenv(&env, "val1", "3", 0));
143 EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
144 EXPECT_EQ(0, minijail_setenv(&env, "val1", "3", 1));
145 EXPECT_EQ("val1=3\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
146 EXPECT_EQ(0, minijail_setenv(&env, "val2", "4", 1));
147 EXPECT_EQ("val1=3\nval2=4\ndup=1\ndup=2\nempty=\n", dump_env(env));
148 EXPECT_EQ(0, minijail_setenv(&env, "dup", "5", 1));
149 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\n", dump_env(env));
150 EXPECT_EQ(0, minijail_setenv(&env, "empty", "6", 1));
151 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=6\n", dump_env(env));
152 EXPECT_EQ(0, minijail_setenv(&env, "empty", "", 1));
153 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\n", dump_env(env));
154 EXPECT_EQ(0, minijail_setenv(&env, "new1", "7", 0));
155 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\n", dump_env(env));
156 EXPECT_EQ(0, minijail_setenv(&env, "new2", "8", 1));
157 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
158 dump_env(env));
159
160 minijail_free_env(env);
161}
Mike Frysinger70b15b82020-09-03 18:10:57 -0400162
163TEST(parse_constant, unsigned) {
164 char *end;
165 long int c = 0;
166 std::string constant;
167
168#if defined(BITS32)
169 constant = "0x80000000";
170 c = parse_constant(const_cast<char*>(constant.data()), &end);
171 EXPECT_EQ(0x80000000U, static_cast<unsigned long int>(c));
172
173#elif defined(BITS64)
174 constant = "0x8000000000000000";
175 c = parse_constant(const_cast<char*>(constant.data()), &end);
176 EXPECT_EQ(0x8000000000000000UL, static_cast<unsigned long int>(c));
177
178#else
179# error "unknown bits!"
180#endif
181}
182
183TEST(parse_constant, unsigned_toobig) {
184 char *end;
185 long int c = 0;
186 std::string constant;
187
188#if defined(BITS32)
189 constant = "0x100000000"; // Too big for 32-bit unsigned long int.
190 c = parse_constant(const_cast<char*>(constant.data()), &end);
191 // Error case should return 0.
192 EXPECT_EQ(0, c);
193
194#elif defined(BITS64)
195 constant = "0x10000000000000000";
196 c = parse_constant(const_cast<char*>(constant.data()), &end);
197 // Error case should return 0.
198 EXPECT_EQ(0, c);
199
200#else
201# error "unknown bits!"
202#endif
203}
204
205TEST(parse_constant, signed) {
206 char *end;
207 long int c = 0;
208 std::string constant = "-1";
209 c = parse_constant(const_cast<char*>(constant.data()), &end);
210 EXPECT_EQ(-1, c);
211}
212
213TEST(parse_constant, signed_toonegative) {
214 char *end;
215 long int c = 0;
216 std::string constant;
217
218#if defined(BITS32)
219 constant = "-0x80000001";
220 c = parse_constant(const_cast<char*>(constant.data()), &end);
221 // Error case should return 0.
222 EXPECT_EQ(0, c);
223
224#elif defined(BITS64)
225 constant = "-0x8000000000000001";
226 c = parse_constant(const_cast<char*>(constant.data()), &end);
227 // Error case should return 0.
228 EXPECT_EQ(0, c);
229
230#else
231# error "unknown bits!"
232#endif
233}
234
235TEST(parse_constant, complements) {
236 char* end;
237 long int c = 0;
238 std::string constant;
239
240#if defined(BITS32)
241 constant = "~0x005AF0FF|~0xFFA50FFF";
242 c = parse_constant(const_cast<char*>(constant.data()), &end);
243 EXPECT_EQ(c, 0xFFFFFF00);
244 constant = "0x0F|~(0x005AF000|0x00A50FFF)|0xF0";
245 c = parse_constant(const_cast<char*>(constant.data()), &end);
246 EXPECT_EQ(c, 0xFF0000FF);
247
248#elif defined(BITS64)
249 constant = "~0x00005A5AF0F0FFFF|~0xFFFFA5A50F0FFFFF";
250 c = parse_constant(const_cast<char*>(constant.data()), &end);
251 EXPECT_EQ(c, 0xFFFFFFFFFFFF0000UL);
252 constant = "0x00FF|~(0x00005A5AF0F00000|0x0000A5A50F0FFFFF)|0xFF00";
253 c = parse_constant(const_cast<char*>(constant.data()), &end);
254 EXPECT_EQ(c, 0xFFFF00000000FFFFUL);
255
256#else
257# error "unknown bits!"
258#endif
259}
260
261TEST(parse_constant, parenthesized_expresions) {
262 char* end;
263
264 const std::vector<const char*> bad_expressions = {
265 "(1", "1)", "(1)1", "|(1)", "(1)|", "()",
266 "(", "((", "(()", "(()1", "1(0)",
267 };
268 for (const auto* expression : bad_expressions) {
269 std::string mutable_expression = expression;
270 long int c =
271 parse_constant(const_cast<char*>(mutable_expression.data()), &end);
272 EXPECT_EQ(reinterpret_cast<const void*>(end),
273 reinterpret_cast<const void*>(mutable_expression.data()));
274 // Error case should return 0.
275 EXPECT_EQ(c, 0) << "For expression: \"" << expression << "\"";
276 }
277
278 const std::vector<const char*> good_expressions = {
279 "(3)", "(1)|2", "1|(2)", "(1)|(2)", "((3))", "0|(1|2)", "(0|1|2)",
280 };
281 for (const auto* expression : good_expressions) {
282 std::string mutable_expression = expression;
283 long int c =
284 parse_constant(const_cast<char*>(mutable_expression.data()), &end);
285 EXPECT_EQ(c, 3) << "For expression: \"" << expression << "\"";
286 }
287}
288
289TEST(parse_size, complete) {
290 size_t size;
291
292 ASSERT_EQ(0, parse_size(&size, "42"));
293 ASSERT_EQ(42U, size);
294
295 ASSERT_EQ(0, parse_size(&size, "16K"));
296 ASSERT_EQ(16384U, size);
297
298 ASSERT_EQ(0, parse_size(&size, "1M"));
299 ASSERT_EQ(1024U * 1024, size);
300
301 uint64_t gigabyte = 1024ULL * 1024 * 1024;
302 ASSERT_EQ(0, parse_size(&size, "3G"));
303 ASSERT_EQ(3U, size / gigabyte);
304 ASSERT_EQ(0U, size % gigabyte);
305
306 ASSERT_EQ(0, parse_size(&size, "4294967294"));
307 ASSERT_EQ(3U, size / gigabyte);
308 ASSERT_EQ(gigabyte - 2, size % gigabyte);
309
310#if __WORDSIZE == 64
311 uint64_t exabyte = gigabyte * 1024 * 1024 * 1024;
312 ASSERT_EQ(0, parse_size(&size, "9E"));
313 ASSERT_EQ(9U, size / exabyte);
314 ASSERT_EQ(0U, size % exabyte);
315
316 ASSERT_EQ(0, parse_size(&size, "15E"));
317 ASSERT_EQ(15U, size / exabyte);
318 ASSERT_EQ(0U, size % exabyte);
319
320 ASSERT_EQ(0, parse_size(&size, "18446744073709551614"));
321 ASSERT_EQ(15U, size / exabyte);
322 ASSERT_EQ(exabyte - 2, size % exabyte);
323
324 ASSERT_EQ(-ERANGE, parse_size(&size, "16E"));
325 ASSERT_EQ(-ERANGE, parse_size(&size, "19E"));
326 ASSERT_EQ(-EINVAL, parse_size(&size, "7GTPE"));
327#elif __WORDSIZE == 32
328 ASSERT_EQ(-ERANGE, parse_size(&size, "5G"));
329 ASSERT_EQ(-ERANGE, parse_size(&size, "9G"));
330 ASSERT_EQ(-ERANGE, parse_size(&size, "9E"));
331 ASSERT_EQ(-ERANGE, parse_size(&size, "7GTPE"));
332#endif
333
334 ASSERT_EQ(-EINVAL, parse_size(&size, ""));
335 ASSERT_EQ(-EINVAL, parse_size(&size, "14u"));
336 ASSERT_EQ(-EINVAL, parse_size(&size, "14.2G"));
337 ASSERT_EQ(-EINVAL, parse_size(&size, "-1G"));
338 ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
339}