xref: /aosp_15_r20/external/minijail/util_unittest.cc (revision 4b9c6d91573e8b3a96609339b46361b5476dd0f9)
1*4b9c6d91SCole Faust /* Copyright 2018 The ChromiumOS Authors
2*4b9c6d91SCole Faust  * Use of this source code is governed by a BSD-style license that can be
3*4b9c6d91SCole Faust  * found in the LICENSE file.
4*4b9c6d91SCole Faust  *
5*4b9c6d91SCole Faust  * Test util.[ch] module code using gtest.
6*4b9c6d91SCole Faust  */
7*4b9c6d91SCole Faust 
8*4b9c6d91SCole Faust #include <stdio.h>
9*4b9c6d91SCole Faust #include <stdlib.h>
10*4b9c6d91SCole Faust #include <string.h>
11*4b9c6d91SCole Faust #include <sys/stat.h>
12*4b9c6d91SCole Faust #include <unistd.h>
13*4b9c6d91SCole Faust 
14*4b9c6d91SCole Faust #include <gtest/gtest.h>
15*4b9c6d91SCole Faust 
16*4b9c6d91SCole Faust #include "bpf.h"
17*4b9c6d91SCole Faust #include "test_util.h"
18*4b9c6d91SCole Faust #include "util.h"
19*4b9c6d91SCole Faust 
20*4b9c6d91SCole Faust namespace {
21*4b9c6d91SCole Faust 
dump_env(const char * const * env)22*4b9c6d91SCole Faust std::string dump_env(const char *const *env) {
23*4b9c6d91SCole Faust   std::string result;
24*4b9c6d91SCole Faust   for (; *env; ++env) {
25*4b9c6d91SCole Faust     result += *env;
26*4b9c6d91SCole Faust     result += "\n";
27*4b9c6d91SCole Faust   }
28*4b9c6d91SCole Faust 
29*4b9c6d91SCole Faust   return result;
30*4b9c6d91SCole Faust }
31*4b9c6d91SCole Faust 
32*4b9c6d91SCole Faust }  // namespace
33*4b9c6d91SCole Faust 
34*4b9c6d91SCole Faust // Sanity check for the strip func.
TEST(strip,basic)35*4b9c6d91SCole Faust TEST(strip, basic) {
36*4b9c6d91SCole Faust   char str[] = " foo\t";
37*4b9c6d91SCole Faust   ASSERT_EQ("foo", std::string(strip(str)));
38*4b9c6d91SCole Faust }
39*4b9c6d91SCole Faust 
40*4b9c6d91SCole Faust // Make sure we don't crash with various "null"-like inputs.
TEST(tokenize,null_stringp)41*4b9c6d91SCole Faust TEST(tokenize, null_stringp) {
42*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(nullptr, nullptr));
43*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(nullptr, ""));
44*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(nullptr, ","));
45*4b9c6d91SCole Faust 
46*4b9c6d91SCole Faust   char *p = nullptr;
47*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(&p, nullptr));
48*4b9c6d91SCole Faust }
49*4b9c6d91SCole Faust 
50*4b9c6d91SCole Faust // Make sure we don't crash with various "null"-like inputs.
TEST(tokenize,null_delim)51*4b9c6d91SCole Faust TEST(tokenize, null_delim) {
52*4b9c6d91SCole Faust   char str[] = "a,b,c";
53*4b9c6d91SCole Faust   char *p = str;
54*4b9c6d91SCole Faust   ASSERT_EQ(str, tokenize(&p, nullptr));
55*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, p);
56*4b9c6d91SCole Faust   ASSERT_EQ(str, std::string("a,b,c"));
57*4b9c6d91SCole Faust 
58*4b9c6d91SCole Faust   p = str;
59*4b9c6d91SCole Faust   ASSERT_EQ(str, tokenize(&p, ""));
60*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, p);
61*4b9c6d91SCole Faust   ASSERT_EQ(str, std::string("a,b,c"));
62*4b9c6d91SCole Faust }
63*4b9c6d91SCole Faust 
64*4b9c6d91SCole Faust // Sanity check for the tokenize func.
TEST(tokenize,basic)65*4b9c6d91SCole Faust TEST(tokenize, basic) {
66*4b9c6d91SCole Faust   char str[] = "a,b,c";
67*4b9c6d91SCole Faust   char *p = str;
68*4b9c6d91SCole Faust   ASSERT_EQ("a", std::string(tokenize(&p, ",")));
69*4b9c6d91SCole Faust   ASSERT_EQ("b", std::string(tokenize(&p, ",")));
70*4b9c6d91SCole Faust   ASSERT_EQ("c", std::string(tokenize(&p, ",")));
71*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, p);
72*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(&p, ","));
73*4b9c6d91SCole Faust }
74*4b9c6d91SCole Faust 
75*4b9c6d91SCole Faust // Check edge case with an empty string.
TEST(tokenize,empty_string)76*4b9c6d91SCole Faust TEST(tokenize, empty_string) {
77*4b9c6d91SCole Faust   char str[] = "";
78*4b9c6d91SCole Faust   char *p = str;
79*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
80*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, p);
81*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(&p, ","));
82*4b9c6d91SCole Faust }
83*4b9c6d91SCole Faust 
84*4b9c6d91SCole Faust // Check behavior with empty tokens at the start/middle/end.
TEST(tokenize,empty_tokens)85*4b9c6d91SCole Faust TEST(tokenize, empty_tokens) {
86*4b9c6d91SCole Faust   char str[] = ",,a,b,,,c,,";
87*4b9c6d91SCole Faust   char *p = str;
88*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
89*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
90*4b9c6d91SCole Faust   ASSERT_EQ("a", std::string(tokenize(&p, ",")));
91*4b9c6d91SCole Faust   ASSERT_EQ("b", std::string(tokenize(&p, ",")));
92*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
93*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
94*4b9c6d91SCole Faust   ASSERT_EQ("c", std::string(tokenize(&p, ",")));
95*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
96*4b9c6d91SCole Faust   ASSERT_EQ("", std::string(tokenize(&p, ",")));
97*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, p);
98*4b9c6d91SCole Faust   ASSERT_EQ(nullptr, tokenize(&p, ","));
99*4b9c6d91SCole Faust }
100*4b9c6d91SCole Faust 
101*4b9c6d91SCole Faust // Check environment manipulation functions.
TEST(environment,copy_and_modify)102*4b9c6d91SCole Faust TEST(environment, copy_and_modify) {
103*4b9c6d91SCole Faust   minijail_free_env(nullptr);
104*4b9c6d91SCole Faust 
105*4b9c6d91SCole Faust   char **env = minijail_copy_env(nullptr);
106*4b9c6d91SCole Faust   EXPECT_EQ("", dump_env(env));
107*4b9c6d91SCole Faust   minijail_free_env(env);
108*4b9c6d91SCole Faust 
109*4b9c6d91SCole Faust   const char *const kConstEnv[] = {
110*4b9c6d91SCole Faust     "val1=1",
111*4b9c6d91SCole Faust     "val2=2",
112*4b9c6d91SCole Faust     "dup=1",
113*4b9c6d91SCole Faust     "dup=2",
114*4b9c6d91SCole Faust     "empty=",
115*4b9c6d91SCole Faust     nullptr,
116*4b9c6d91SCole Faust   };
117*4b9c6d91SCole Faust 
118*4b9c6d91SCole Faust   // libc unfortunately uses char* const[] as the type for the environment, and
119*4b9c6d91SCole Faust   // we match that. It's actually missing a const-ness of the chars making up
120*4b9c6d91SCole Faust   // the environment strings, but we need that to initialize the |kEnv|
121*4b9c6d91SCole Faust   // constant. Hence, do a cast here to force things into alignment...
122*4b9c6d91SCole Faust   char* const* kEnv = const_cast<char* const*>(kConstEnv);
123*4b9c6d91SCole Faust 
124*4b9c6d91SCole Faust   env = minijail_copy_env(kEnv);
125*4b9c6d91SCole Faust   EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
126*4b9c6d91SCole Faust   minijail_free_env(env);
127*4b9c6d91SCole Faust 
128*4b9c6d91SCole Faust   env = minijail_copy_env(kEnv);
129*4b9c6d91SCole Faust   EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
130*4b9c6d91SCole Faust 
131*4b9c6d91SCole Faust   EXPECT_EQ(EINVAL, minijail_setenv(nullptr, "val1", "3", 1));
132*4b9c6d91SCole Faust   char **env_ret = nullptr;
133*4b9c6d91SCole Faust   EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "val1", "3", 1));
134*4b9c6d91SCole Faust 
135*4b9c6d91SCole Faust   env_ret = env;
136*4b9c6d91SCole Faust   EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, nullptr, "3", 1));
137*4b9c6d91SCole Faust   EXPECT_EQ(env, env_ret);
138*4b9c6d91SCole Faust   EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "", "3", 1));
139*4b9c6d91SCole Faust   EXPECT_EQ(env, env_ret);
140*4b9c6d91SCole Faust   EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "", nullptr, 1));
141*4b9c6d91SCole Faust   EXPECT_EQ(env, env_ret);
142*4b9c6d91SCole Faust 
143*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "val1", "3", 0));
144*4b9c6d91SCole Faust   EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
145*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "val1", "3", 1));
146*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
147*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "val2", "4", 1));
148*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=1\ndup=2\nempty=\n", dump_env(env));
149*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "dup", "5", 1));
150*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\n", dump_env(env));
151*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "empty", "6", 1));
152*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=6\n", dump_env(env));
153*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "empty", "", 1));
154*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\n", dump_env(env));
155*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "new1", "7", 0));
156*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\n", dump_env(env));
157*4b9c6d91SCole Faust   EXPECT_EQ(0, minijail_setenv(&env, "new2", "8", 1));
158*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
159*4b9c6d91SCole Faust             dump_env(env));
160*4b9c6d91SCole Faust 
161*4b9c6d91SCole Faust   EXPECT_EQ(nullptr, minijail_getenv(nullptr, "dup"));
162*4b9c6d91SCole Faust   EXPECT_EQ(nullptr, minijail_getenv(nullptr, nullptr));
163*4b9c6d91SCole Faust   EXPECT_EQ(nullptr, minijail_getenv(env, nullptr));
164*4b9c6d91SCole Faust   EXPECT_EQ(nullptr, minijail_getenv(env, "dup="));
165*4b9c6d91SCole Faust   EXPECT_EQ(nullptr, minijail_getenv(env, "du"));
166*4b9c6d91SCole Faust   EXPECT_EQ(std::string("8"), minijail_getenv(env, "new2"));
167*4b9c6d91SCole Faust   EXPECT_EQ(std::string("3"), minijail_getenv(env, "val1"));
168*4b9c6d91SCole Faust   EXPECT_EQ(std::string("5"), minijail_getenv(env, "dup"));
169*4b9c6d91SCole Faust 
170*4b9c6d91SCole Faust   EXPECT_EQ(false, minijail_unsetenv(env, "nonexisting"));
171*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
172*4b9c6d91SCole Faust             dump_env(env));
173*4b9c6d91SCole Faust   EXPECT_EQ(false, minijail_unsetenv(env, ""));
174*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
175*4b9c6d91SCole Faust             dump_env(env));
176*4b9c6d91SCole Faust   EXPECT_EQ(false, minijail_unsetenv(env, nullptr));
177*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
178*4b9c6d91SCole Faust             dump_env(env));
179*4b9c6d91SCole Faust   EXPECT_EQ(false, minijail_unsetenv(nullptr, nullptr));
180*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
181*4b9c6d91SCole Faust             dump_env(env));
182*4b9c6d91SCole Faust   EXPECT_EQ(false, minijail_unsetenv(nullptr, "nonexisting"));
183*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
184*4b9c6d91SCole Faust             dump_env(env));
185*4b9c6d91SCole Faust   EXPECT_EQ(false, minijail_unsetenv(env, "val1="));
186*4b9c6d91SCole Faust   EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
187*4b9c6d91SCole Faust             dump_env(env));
188*4b9c6d91SCole Faust   EXPECT_EQ(true, minijail_unsetenv(env, "val1"));
189*4b9c6d91SCole Faust   EXPECT_EQ("new2=8\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\n", dump_env(env));
190*4b9c6d91SCole Faust   EXPECT_EQ(true, minijail_unsetenv(env, "empty"));
191*4b9c6d91SCole Faust   EXPECT_EQ("new2=8\nval2=4\ndup=5\ndup=2\nnew1=7\n", dump_env(env));
192*4b9c6d91SCole Faust   EXPECT_EQ(true, minijail_unsetenv(env, "new2"));
193*4b9c6d91SCole Faust   EXPECT_EQ("new1=7\nval2=4\ndup=5\ndup=2\n", dump_env(env));
194*4b9c6d91SCole Faust   EXPECT_EQ(true, minijail_unsetenv(env, "new1"));
195*4b9c6d91SCole Faust   EXPECT_EQ("dup=2\nval2=4\ndup=5\n", dump_env(env));
196*4b9c6d91SCole Faust 
197*4b9c6d91SCole Faust   minijail_free_env(env);
198*4b9c6d91SCole Faust }
199*4b9c6d91SCole Faust 
TEST(parse_single_constant,formats)200*4b9c6d91SCole Faust TEST(parse_single_constant, formats) {
201*4b9c6d91SCole Faust   char *end;
202*4b9c6d91SCole Faust   long int c = 0;
203*4b9c6d91SCole Faust   std::string constant;
204*4b9c6d91SCole Faust 
205*4b9c6d91SCole Faust   // Check base 10 works.
206*4b9c6d91SCole Faust   constant = "1234";
207*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
208*4b9c6d91SCole Faust   EXPECT_EQ(1234, c);
209*4b9c6d91SCole Faust 
210*4b9c6d91SCole Faust   // Check base 16 works.
211*4b9c6d91SCole Faust   constant = "0x1234";
212*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
213*4b9c6d91SCole Faust   EXPECT_EQ(0x1234, c);
214*4b9c6d91SCole Faust 
215*4b9c6d91SCole Faust   // Check base 8 works.
216*4b9c6d91SCole Faust   constant = "01234";
217*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
218*4b9c6d91SCole Faust   EXPECT_EQ(01234, c);
219*4b9c6d91SCole Faust }
220*4b9c6d91SCole Faust 
TEST(parse_constant,unsigned)221*4b9c6d91SCole Faust TEST(parse_constant, unsigned) {
222*4b9c6d91SCole Faust   char *end;
223*4b9c6d91SCole Faust   long int c = 0;
224*4b9c6d91SCole Faust   std::string constant;
225*4b9c6d91SCole Faust 
226*4b9c6d91SCole Faust #if defined(BITS32)
227*4b9c6d91SCole Faust   constant = "0x80000000";
228*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
229*4b9c6d91SCole Faust   EXPECT_EQ(0x80000000U, static_cast<unsigned long int>(c));
230*4b9c6d91SCole Faust 
231*4b9c6d91SCole Faust #elif defined(BITS64)
232*4b9c6d91SCole Faust   constant = "0x8000000000000000";
233*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
234*4b9c6d91SCole Faust   EXPECT_EQ(0x8000000000000000UL, static_cast<unsigned long int>(c));
235*4b9c6d91SCole Faust 
236*4b9c6d91SCole Faust #else
237*4b9c6d91SCole Faust # error "unknown bits!"
238*4b9c6d91SCole Faust #endif
239*4b9c6d91SCole Faust }
240*4b9c6d91SCole Faust 
TEST(parse_constant,unsigned_toobig)241*4b9c6d91SCole Faust TEST(parse_constant, unsigned_toobig) {
242*4b9c6d91SCole Faust   char *end;
243*4b9c6d91SCole Faust   long int c = 0;
244*4b9c6d91SCole Faust   std::string constant;
245*4b9c6d91SCole Faust 
246*4b9c6d91SCole Faust #if defined(BITS32)
247*4b9c6d91SCole Faust   constant = "0x100000000";  // Too big for 32-bit unsigned long int.
248*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
249*4b9c6d91SCole Faust   // Error case should return 0.
250*4b9c6d91SCole Faust   EXPECT_EQ(0, c);
251*4b9c6d91SCole Faust 
252*4b9c6d91SCole Faust #elif defined(BITS64)
253*4b9c6d91SCole Faust   constant = "0x10000000000000000";
254*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
255*4b9c6d91SCole Faust   // Error case should return 0.
256*4b9c6d91SCole Faust   EXPECT_EQ(0, c);
257*4b9c6d91SCole Faust 
258*4b9c6d91SCole Faust #else
259*4b9c6d91SCole Faust # error "unknown bits!"
260*4b9c6d91SCole Faust #endif
261*4b9c6d91SCole Faust }
262*4b9c6d91SCole Faust 
TEST(parse_constant,signed)263*4b9c6d91SCole Faust TEST(parse_constant, signed) {
264*4b9c6d91SCole Faust   char *end;
265*4b9c6d91SCole Faust   long int c = 0;
266*4b9c6d91SCole Faust   std::string constant = "-1";
267*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
268*4b9c6d91SCole Faust   EXPECT_EQ(-1, c);
269*4b9c6d91SCole Faust }
270*4b9c6d91SCole Faust 
TEST(parse_constant,signed_toonegative)271*4b9c6d91SCole Faust TEST(parse_constant, signed_toonegative) {
272*4b9c6d91SCole Faust   char *end;
273*4b9c6d91SCole Faust   long int c = 0;
274*4b9c6d91SCole Faust   std::string constant;
275*4b9c6d91SCole Faust 
276*4b9c6d91SCole Faust #if defined(BITS32)
277*4b9c6d91SCole Faust   constant = "-0x80000001";
278*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
279*4b9c6d91SCole Faust   // Error case should return 0.
280*4b9c6d91SCole Faust   EXPECT_EQ(0, c);
281*4b9c6d91SCole Faust 
282*4b9c6d91SCole Faust #elif defined(BITS64)
283*4b9c6d91SCole Faust   constant = "-0x8000000000000001";
284*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
285*4b9c6d91SCole Faust   // Error case should return 0.
286*4b9c6d91SCole Faust   EXPECT_EQ(0, c);
287*4b9c6d91SCole Faust 
288*4b9c6d91SCole Faust #else
289*4b9c6d91SCole Faust # error "unknown bits!"
290*4b9c6d91SCole Faust #endif
291*4b9c6d91SCole Faust }
292*4b9c6d91SCole Faust 
TEST(parse_constant,complements)293*4b9c6d91SCole Faust TEST(parse_constant, complements) {
294*4b9c6d91SCole Faust   char* end;
295*4b9c6d91SCole Faust   long int c = 0;
296*4b9c6d91SCole Faust   std::string constant;
297*4b9c6d91SCole Faust 
298*4b9c6d91SCole Faust #if defined(BITS32)
299*4b9c6d91SCole Faust   constant = "~0x005AF0FF|~0xFFA50FFF";
300*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
301*4b9c6d91SCole Faust   EXPECT_EQ(c, 0xFFFFFF00);
302*4b9c6d91SCole Faust   constant = "0x0F|~(0x005AF000|0x00A50FFF)|0xF0";
303*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
304*4b9c6d91SCole Faust   EXPECT_EQ(c, 0xFF0000FF);
305*4b9c6d91SCole Faust 
306*4b9c6d91SCole Faust #elif defined(BITS64)
307*4b9c6d91SCole Faust   constant = "~0x00005A5AF0F0FFFF|~0xFFFFA5A50F0FFFFF";
308*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
309*4b9c6d91SCole Faust   EXPECT_EQ(c, 0xFFFFFFFFFFFF0000UL);
310*4b9c6d91SCole Faust   constant = "0x00FF|~(0x00005A5AF0F00000|0x0000A5A50F0FFFFF)|0xFF00";
311*4b9c6d91SCole Faust   c = parse_constant(const_cast<char*>(constant.data()), &end);
312*4b9c6d91SCole Faust   EXPECT_EQ(c, 0xFFFF00000000FFFFUL);
313*4b9c6d91SCole Faust 
314*4b9c6d91SCole Faust #else
315*4b9c6d91SCole Faust # error "unknown bits!"
316*4b9c6d91SCole Faust #endif
317*4b9c6d91SCole Faust }
318*4b9c6d91SCole Faust 
TEST(parse_constant,parenthesized_expresions)319*4b9c6d91SCole Faust TEST(parse_constant, parenthesized_expresions) {
320*4b9c6d91SCole Faust   char* end;
321*4b9c6d91SCole Faust 
322*4b9c6d91SCole Faust   const std::vector<const char*> bad_expressions = {
323*4b9c6d91SCole Faust       "(1", "1)", "(1)1", "|(1)", "(1)|", "()",
324*4b9c6d91SCole Faust       "(",  "((", "(()",  "(()1", "1(0)",
325*4b9c6d91SCole Faust   };
326*4b9c6d91SCole Faust   for (const auto* expression : bad_expressions) {
327*4b9c6d91SCole Faust     std::string mutable_expression = expression;
328*4b9c6d91SCole Faust     long int c =
329*4b9c6d91SCole Faust         parse_constant(const_cast<char*>(mutable_expression.data()), &end);
330*4b9c6d91SCole Faust     EXPECT_EQ(reinterpret_cast<const void*>(end),
331*4b9c6d91SCole Faust               reinterpret_cast<const void*>(mutable_expression.data()));
332*4b9c6d91SCole Faust     // Error case should return 0.
333*4b9c6d91SCole Faust     EXPECT_EQ(c, 0) << "For expression: \"" << expression << "\"";
334*4b9c6d91SCole Faust   }
335*4b9c6d91SCole Faust 
336*4b9c6d91SCole Faust   const std::vector<const char*> good_expressions = {
337*4b9c6d91SCole Faust       "(3)", "(1)|2", "1|(2)", "(1)|(2)", "((3))", "0|(1|2)", "(0|1|2)",
338*4b9c6d91SCole Faust   };
339*4b9c6d91SCole Faust   for (const auto* expression : good_expressions) {
340*4b9c6d91SCole Faust     std::string mutable_expression = expression;
341*4b9c6d91SCole Faust     long int c =
342*4b9c6d91SCole Faust         parse_constant(const_cast<char*>(mutable_expression.data()), &end);
343*4b9c6d91SCole Faust     EXPECT_EQ(c, 3) << "For expression: \"" << expression << "\"";
344*4b9c6d91SCole Faust   }
345*4b9c6d91SCole Faust }
346*4b9c6d91SCole Faust 
TEST(parse_size,complete)347*4b9c6d91SCole Faust TEST(parse_size, complete) {
348*4b9c6d91SCole Faust   size_t size;
349*4b9c6d91SCole Faust 
350*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "42"));
351*4b9c6d91SCole Faust   ASSERT_EQ(42U, size);
352*4b9c6d91SCole Faust 
353*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "16K"));
354*4b9c6d91SCole Faust   ASSERT_EQ(16384U, size);
355*4b9c6d91SCole Faust 
356*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "1M"));
357*4b9c6d91SCole Faust   ASSERT_EQ(1024U * 1024, size);
358*4b9c6d91SCole Faust 
359*4b9c6d91SCole Faust   uint64_t gigabyte = 1024ULL * 1024 * 1024;
360*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "3G"));
361*4b9c6d91SCole Faust   ASSERT_EQ(3U, size / gigabyte);
362*4b9c6d91SCole Faust   ASSERT_EQ(0U, size % gigabyte);
363*4b9c6d91SCole Faust 
364*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "4294967294"));
365*4b9c6d91SCole Faust   ASSERT_EQ(3U, size / gigabyte);
366*4b9c6d91SCole Faust   ASSERT_EQ(gigabyte - 2, size % gigabyte);
367*4b9c6d91SCole Faust 
368*4b9c6d91SCole Faust #if __WORDSIZE == 64
369*4b9c6d91SCole Faust   uint64_t exabyte = gigabyte * 1024 * 1024 * 1024;
370*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "9E"));
371*4b9c6d91SCole Faust   ASSERT_EQ(9U, size / exabyte);
372*4b9c6d91SCole Faust   ASSERT_EQ(0U, size % exabyte);
373*4b9c6d91SCole Faust 
374*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "15E"));
375*4b9c6d91SCole Faust   ASSERT_EQ(15U, size / exabyte);
376*4b9c6d91SCole Faust   ASSERT_EQ(0U, size % exabyte);
377*4b9c6d91SCole Faust 
378*4b9c6d91SCole Faust   ASSERT_EQ(0, parse_size(&size, "18446744073709551614"));
379*4b9c6d91SCole Faust   ASSERT_EQ(15U, size / exabyte);
380*4b9c6d91SCole Faust   ASSERT_EQ(exabyte - 2, size % exabyte);
381*4b9c6d91SCole Faust 
382*4b9c6d91SCole Faust   ASSERT_EQ(-ERANGE, parse_size(&size, "16E"));
383*4b9c6d91SCole Faust   ASSERT_EQ(-ERANGE, parse_size(&size, "19E"));
384*4b9c6d91SCole Faust   ASSERT_EQ(-EINVAL, parse_size(&size, "7GTPE"));
385*4b9c6d91SCole Faust #elif __WORDSIZE == 32
386*4b9c6d91SCole Faust   ASSERT_EQ(-ERANGE, parse_size(&size, "5G"));
387*4b9c6d91SCole Faust   ASSERT_EQ(-ERANGE, parse_size(&size, "9G"));
388*4b9c6d91SCole Faust   ASSERT_EQ(-ERANGE, parse_size(&size, "9E"));
389*4b9c6d91SCole Faust   ASSERT_EQ(-ERANGE, parse_size(&size, "7GTPE"));
390*4b9c6d91SCole Faust #endif
391*4b9c6d91SCole Faust 
392*4b9c6d91SCole Faust   ASSERT_EQ(-EINVAL, parse_size(&size, ""));
393*4b9c6d91SCole Faust   ASSERT_EQ(-EINVAL, parse_size(&size, "14u"));
394*4b9c6d91SCole Faust   ASSERT_EQ(-EINVAL, parse_size(&size, "14.2G"));
395*4b9c6d91SCole Faust   ASSERT_EQ(-EINVAL, parse_size(&size, "-1G"));
396*4b9c6d91SCole Faust   ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
397*4b9c6d91SCole Faust }
398*4b9c6d91SCole Faust 
TEST(path_join,basic)399*4b9c6d91SCole Faust TEST(path_join, basic) {
400*4b9c6d91SCole Faust   char *path = path_join("a", "b");
401*4b9c6d91SCole Faust   ASSERT_EQ(std::string("a/b"), path);
402*4b9c6d91SCole Faust   free(path);
403*4b9c6d91SCole Faust }
404*4b9c6d91SCole Faust 
TEST(path_is_parent,simple)405*4b9c6d91SCole Faust TEST(path_is_parent, simple) {
406*4b9c6d91SCole Faust   EXPECT_TRUE(path_is_parent("/dev", "/dev/rtc"));
407*4b9c6d91SCole Faust   EXPECT_TRUE(path_is_parent("/dev/", "/dev/rtc"));
408*4b9c6d91SCole Faust   EXPECT_TRUE(path_is_parent("/sys", "/sys/power"));
409*4b9c6d91SCole Faust   EXPECT_TRUE(path_is_parent("/sys/power", "/sys/power/something"));
410*4b9c6d91SCole Faust   EXPECT_TRUE(path_is_parent("/sys", "/sys/sys/power"));
411*4b9c6d91SCole Faust 
412*4b9c6d91SCole Faust   EXPECT_FALSE(path_is_parent("/dev", ""));
413*4b9c6d91SCole Faust   EXPECT_FALSE(path_is_parent("/dev", "/sys"));
414*4b9c6d91SCole Faust   EXPECT_FALSE(path_is_parent("/dev", "dev"));
415*4b9c6d91SCole Faust   EXPECT_FALSE(path_is_parent("/dev", "/sys/dev"));
416*4b9c6d91SCole Faust   EXPECT_FALSE(path_is_parent("/dev", "/device"));
417*4b9c6d91SCole Faust }
418*4b9c6d91SCole Faust 
TEST(getmultiline,basic)419*4b9c6d91SCole Faust TEST(getmultiline, basic) {
420*4b9c6d91SCole Faust   std::string config =
421*4b9c6d91SCole Faust            "\n"
422*4b9c6d91SCole Faust            "mount = none\n"
423*4b9c6d91SCole Faust            "mount =\\\n"
424*4b9c6d91SCole Faust            "none\n"
425*4b9c6d91SCole Faust            "binding = none,/tmp\n"
426*4b9c6d91SCole Faust            "binding = none,\\\n"
427*4b9c6d91SCole Faust            "/tmp";
428*4b9c6d91SCole Faust   FILE *config_file = write_to_pipe(config);
429*4b9c6d91SCole Faust   ASSERT_NE(config_file, nullptr);
430*4b9c6d91SCole Faust 
431*4b9c6d91SCole Faust   char *line = NULL;
432*4b9c6d91SCole Faust   size_t len = 0;
433*4b9c6d91SCole Faust   ASSERT_EQ(0, getmultiline(&line, &len, config_file));
434*4b9c6d91SCole Faust   EXPECT_EQ(std::string(line), "");
435*4b9c6d91SCole Faust   ASSERT_EQ(12, getmultiline(&line, &len, config_file));
436*4b9c6d91SCole Faust   EXPECT_EQ(std::string(line), "mount = none");
437*4b9c6d91SCole Faust   ASSERT_EQ(12, getmultiline(&line, &len, config_file));
438*4b9c6d91SCole Faust   EXPECT_EQ(std::string(line), "mount = none");
439*4b9c6d91SCole Faust   ASSERT_EQ(19, getmultiline(&line, &len, config_file));
440*4b9c6d91SCole Faust   EXPECT_EQ(std::string(line), "binding = none,/tmp");
441*4b9c6d91SCole Faust   ASSERT_EQ(20, getmultiline(&line, &len, config_file));
442*4b9c6d91SCole Faust   EXPECT_EQ(std::string(line), "binding = none, /tmp");
443*4b9c6d91SCole Faust   free(line);
444*4b9c6d91SCole Faust }
445