xref: /aosp_15_r20/external/minijail/config_parser_unittest.cc (revision 4b9c6d91573e8b3a96609339b46361b5476dd0f9)
1*4b9c6d91SCole Faust /* Copyright 2021 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 config_parser.c using gtest.
6*4b9c6d91SCole Faust  */
7*4b9c6d91SCole Faust 
8*4b9c6d91SCole Faust #include <gtest/gtest.h>
9*4b9c6d91SCole Faust #include <string>
10*4b9c6d91SCole Faust 
11*4b9c6d91SCole Faust #include "config_parser.h"
12*4b9c6d91SCole Faust #include "test_util.h"
13*4b9c6d91SCole Faust #include "util.h"
14*4b9c6d91SCole Faust 
15*4b9c6d91SCole Faust namespace {
16*4b9c6d91SCole Faust 
17*4b9c6d91SCole Faust class ConfigFileTest : public ::testing::Test {
18*4b9c6d91SCole Faust protected:
SetUp()19*4b9c6d91SCole Faust   virtual void SetUp() {
20*4b9c6d91SCole Faust     list_ = new_config_entry_list();
21*4b9c6d91SCole Faust     ASSERT_NE(list_, nullptr);
22*4b9c6d91SCole Faust   }
TearDown()23*4b9c6d91SCole Faust   virtual void TearDown() { free_config_entry_list(list_); }
24*4b9c6d91SCole Faust   struct config_entry_list *list_;
25*4b9c6d91SCole Faust };
26*4b9c6d91SCole Faust 
27*4b9c6d91SCole Faust } // namespace
28*4b9c6d91SCole Faust 
TEST(ParsingConfigTest,valid_config_line)29*4b9c6d91SCole Faust TEST(ParsingConfigTest, valid_config_line) {
30*4b9c6d91SCole Faust   ScopedConfigEntry entry(
31*4b9c6d91SCole Faust       (config_entry *)calloc(1, sizeof(struct config_entry)));
32*4b9c6d91SCole Faust   const std::vector<std::string> valid_conf_lines = {
33*4b9c6d91SCole Faust       "mount=none",
34*4b9c6d91SCole Faust       "valueless_key"
35*4b9c6d91SCole Faust       "binding = none",
36*4b9c6d91SCole Faust       "  xyz = abc  ",
37*4b9c6d91SCole Faust   };
38*4b9c6d91SCole Faust 
39*4b9c6d91SCole Faust   for (const auto& conf_line : valid_conf_lines) {
40*4b9c6d91SCole Faust     ASSERT_TRUE(parse_config_line(conf_line.c_str(), entry.get()));
41*4b9c6d91SCole Faust     clear_config_entry(entry.get());
42*4b9c6d91SCole Faust   }
43*4b9c6d91SCole Faust }
44*4b9c6d91SCole Faust 
TEST(ParsingConfigTest,invalid_config_line)45*4b9c6d91SCole Faust TEST(ParsingConfigTest, invalid_config_line) {
46*4b9c6d91SCole Faust   ScopedConfigEntry entry(
47*4b9c6d91SCole Faust       (config_entry *)calloc(1, sizeof(struct config_entry)));
48*4b9c6d91SCole Faust   const std::vector<std::string> invalid_conf_lines = {
49*4b9c6d91SCole Faust       "= none",
50*4b9c6d91SCole Faust       "",
51*4b9c6d91SCole Faust       "empty_arg=",
52*4b9c6d91SCole Faust       "empty_arg=   ",
53*4b9c6d91SCole Faust   };
54*4b9c6d91SCole Faust 
55*4b9c6d91SCole Faust   for (const auto& conf_line : invalid_conf_lines) {
56*4b9c6d91SCole Faust     ASSERT_FALSE(parse_config_line(conf_line.c_str(), entry.get()));
57*4b9c6d91SCole Faust   }
58*4b9c6d91SCole Faust }
59*4b9c6d91SCole Faust 
TEST_F(ConfigFileTest,malformed_config_line)60*4b9c6d91SCole Faust TEST_F(ConfigFileTest, malformed_config_line) {
61*4b9c6d91SCole Faust   std::string config = "% minijail-config-file v0\n"
62*4b9c6d91SCole Faust                        "=malformed";
63*4b9c6d91SCole Faust   ScopedFILE config_file(write_to_pipe(config));
64*4b9c6d91SCole Faust   ASSERT_NE(config_file.get(), nullptr);
65*4b9c6d91SCole Faust 
66*4b9c6d91SCole Faust   bool res = parse_config_file(config_file.get(), list_);
67*4b9c6d91SCole Faust 
68*4b9c6d91SCole Faust   // Policy is malformed, but process should not crash.
69*4b9c6d91SCole Faust   ASSERT_FALSE(res);
70*4b9c6d91SCole Faust   ASSERT_EQ(list_->num_entries, 0);
71*4b9c6d91SCole Faust }
72*4b9c6d91SCole Faust 
TEST_F(ConfigFileTest,bad_directive)73*4b9c6d91SCole Faust TEST_F(ConfigFileTest, bad_directive) {
74*4b9c6d91SCole Faust   std::string config = "% bad-directive\n"
75*4b9c6d91SCole Faust                        "# comments";
76*4b9c6d91SCole Faust   ScopedFILE config_file(write_to_pipe(config));
77*4b9c6d91SCole Faust   ASSERT_NE(config_file.get(), nullptr);
78*4b9c6d91SCole Faust 
79*4b9c6d91SCole Faust   bool res = parse_config_file(config_file.get(), list_);
80*4b9c6d91SCole Faust 
81*4b9c6d91SCole Faust   // Policy is malformed, but process should not crash.
82*4b9c6d91SCole Faust   ASSERT_FALSE(res);
83*4b9c6d91SCole Faust   ASSERT_EQ(list_->num_entries, 0);
84*4b9c6d91SCole Faust }
85*4b9c6d91SCole Faust 
TEST_F(ConfigFileTest,wellformed_single_line)86*4b9c6d91SCole Faust TEST_F(ConfigFileTest, wellformed_single_line) {
87*4b9c6d91SCole Faust   std::string config = "% minijail-config-file v0\n"
88*4b9c6d91SCole Faust                        "# Comments \n"
89*4b9c6d91SCole Faust                        "\n"
90*4b9c6d91SCole Faust                        "uts\n"
91*4b9c6d91SCole Faust                        "mount= xyz\n"
92*4b9c6d91SCole Faust                        "binding = none,/tmp";
93*4b9c6d91SCole Faust   ScopedFILE config_file(write_to_pipe(config));
94*4b9c6d91SCole Faust   ASSERT_NE(config_file.get(), nullptr);
95*4b9c6d91SCole Faust 
96*4b9c6d91SCole Faust   bool res = parse_config_file(config_file.get(), list_);
97*4b9c6d91SCole Faust 
98*4b9c6d91SCole Faust   ASSERT_TRUE(res);
99*4b9c6d91SCole Faust   ASSERT_EQ(list_->num_entries, 3);
100*4b9c6d91SCole Faust   struct config_entry *first_entry = list_->entries;
101*4b9c6d91SCole Faust   struct config_entry *second_entry = list_->entries + 1;
102*4b9c6d91SCole Faust   struct config_entry *third_entry = list_->entries + 2;
103*4b9c6d91SCole Faust   ASSERT_EQ(std::string(first_entry->key), "uts");
104*4b9c6d91SCole Faust   ASSERT_EQ(first_entry->value, nullptr);
105*4b9c6d91SCole Faust   ASSERT_EQ(std::string(second_entry->key), "mount");
106*4b9c6d91SCole Faust   ASSERT_EQ(std::string(second_entry->value), "xyz");
107*4b9c6d91SCole Faust   ASSERT_EQ(std::string(third_entry->key), "binding");
108*4b9c6d91SCole Faust   ASSERT_EQ(std::string(third_entry->value), "none,/tmp");
109*4b9c6d91SCole Faust }
110*4b9c6d91SCole Faust 
TEST_F(ConfigFileTest,wellformed_multi_line)111*4b9c6d91SCole Faust TEST_F(ConfigFileTest, wellformed_multi_line) {
112*4b9c6d91SCole Faust   std::string config = "% minijail-config-file v0\n"
113*4b9c6d91SCole Faust                        "# Comments \n"
114*4b9c6d91SCole Faust                        "\n"
115*4b9c6d91SCole Faust                        "mount = \\\n"
116*4b9c6d91SCole Faust                        "none\n"
117*4b9c6d91SCole Faust                        "binding = none,\\\n"
118*4b9c6d91SCole Faust                        "/tmp";
119*4b9c6d91SCole Faust   ScopedFILE config_file(write_to_pipe(config));
120*4b9c6d91SCole Faust   ASSERT_NE(config_file.get(), nullptr);
121*4b9c6d91SCole Faust 
122*4b9c6d91SCole Faust   int res = parse_config_file(config_file.get(), list_);
123*4b9c6d91SCole Faust 
124*4b9c6d91SCole Faust   ASSERT_TRUE(res);
125*4b9c6d91SCole Faust   ASSERT_EQ(list_->num_entries, 2);
126*4b9c6d91SCole Faust   struct config_entry *first_entry = list_->entries;
127*4b9c6d91SCole Faust   struct config_entry *second_entry = list_->entries + 1;
128*4b9c6d91SCole Faust   ASSERT_EQ(std::string(first_entry->key), "mount");
129*4b9c6d91SCole Faust   ASSERT_EQ(std::string(first_entry->value), "none");
130*4b9c6d91SCole Faust   ASSERT_EQ(std::string(second_entry->key), "binding");
131*4b9c6d91SCole Faust   ASSERT_EQ(std::string(second_entry->value), "none, /tmp");
132*4b9c6d91SCole Faust }
133