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 = "% minijail-config-file v0\n"
62 "=malformed";
63 ScopedFILE config_file(write_to_pipe(config));
64 ASSERT_NE(config_file.get(), nullptr);
65
66 bool res = parse_config_file(config_file.get(), list_);
67
68 // Policy is malformed, but process should not crash.
69 ASSERT_FALSE(res);
70 ASSERT_EQ(list_->num_entries, 0);
71 }
72
TEST_F(ConfigFileTest,bad_directive)73 TEST_F(ConfigFileTest, bad_directive) {
74 std::string config = "% bad-directive\n"
75 "# comments";
76 ScopedFILE config_file(write_to_pipe(config));
77 ASSERT_NE(config_file.get(), nullptr);
78
79 bool res = parse_config_file(config_file.get(), list_);
80
81 // Policy is malformed, but process should not crash.
82 ASSERT_FALSE(res);
83 ASSERT_EQ(list_->num_entries, 0);
84 }
85
TEST_F(ConfigFileTest,wellformed_single_line)86 TEST_F(ConfigFileTest, wellformed_single_line) {
87 std::string config = "% minijail-config-file v0\n"
88 "# Comments \n"
89 "\n"
90 "uts\n"
91 "mount= xyz\n"
92 "binding = none,/tmp";
93 ScopedFILE config_file(write_to_pipe(config));
94 ASSERT_NE(config_file.get(), nullptr);
95
96 bool res = parse_config_file(config_file.get(), list_);
97
98 ASSERT_TRUE(res);
99 ASSERT_EQ(list_->num_entries, 3);
100 struct config_entry *first_entry = list_->entries;
101 struct config_entry *second_entry = list_->entries + 1;
102 struct config_entry *third_entry = list_->entries + 2;
103 ASSERT_EQ(std::string(first_entry->key), "uts");
104 ASSERT_EQ(first_entry->value, nullptr);
105 ASSERT_EQ(std::string(second_entry->key), "mount");
106 ASSERT_EQ(std::string(second_entry->value), "xyz");
107 ASSERT_EQ(std::string(third_entry->key), "binding");
108 ASSERT_EQ(std::string(third_entry->value), "none,/tmp");
109 }
110
TEST_F(ConfigFileTest,wellformed_multi_line)111 TEST_F(ConfigFileTest, wellformed_multi_line) {
112 std::string config = "% minijail-config-file v0\n"
113 "# Comments \n"
114 "\n"
115 "mount = \\\n"
116 "none\n"
117 "binding = none,\\\n"
118 "/tmp";
119 ScopedFILE config_file(write_to_pipe(config));
120 ASSERT_NE(config_file.get(), nullptr);
121
122 int res = parse_config_file(config_file.get(), list_);
123
124 ASSERT_TRUE(res);
125 ASSERT_EQ(list_->num_entries, 2);
126 struct config_entry *first_entry = list_->entries;
127 struct config_entry *second_entry = list_->entries + 1;
128 ASSERT_EQ(std::string(first_entry->key), "mount");
129 ASSERT_EQ(std::string(first_entry->value), "none");
130 ASSERT_EQ(std::string(second_entry->key), "binding");
131 ASSERT_EQ(std::string(second_entry->value), "none, /tmp");
132 }
133