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