config_parser: Add type checking to config map
In order to guarantee the output file is consistent, the
constructed values are checked for safety.
Change-Id: Ib70e369471e9f2f47a1cdb5522f4a3bebc37805e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/config_parser.cpp b/src/config_parser.cpp
index 80f71e7..867d611 100644
--- a/src/config_parser.cpp
+++ b/src/config_parser.cpp
@@ -5,6 +5,7 @@
#include <functional>
#include <iterator>
+#include <stdexcept>
#include <stdplus/exception.hpp>
#include <stdplus/fd/create.hpp>
#include <stdplus/fd/line.hpp>
@@ -67,7 +68,7 @@
{
continue;
}
- return &kit->second.back();
+ return &kit->second.back().get();
}
return nullptr;
}
@@ -79,6 +80,42 @@
[](const Value& v) { return std::string(v); });
}
+void KeyCheck::operator()(const std::string& s)
+{
+ for (auto c : s)
+ {
+ if (c == '\n' || c == '=')
+ {
+ throw std::invalid_argument(
+ fmt::format(FMT_COMPILE("Invalid Config Key: {}"), s));
+ }
+ }
+}
+
+void SectionCheck::operator()(const std::string& s)
+{
+ for (auto c : s)
+ {
+ if (c == '\n' || c == ']')
+ {
+ throw std::invalid_argument(
+ fmt::format(FMT_COMPILE("Invalid Config Section: {}"), s));
+ }
+ }
+}
+
+void ValueCheck::operator()(const std::string& s)
+{
+ for (auto c : s)
+ {
+ if (c == '\n')
+ {
+ throw std::invalid_argument(
+ fmt::format(FMT_COMPILE("Invalid Config Value: {}"), s));
+ }
+ }
+}
+
Parser::Parser(const fs::path& filename)
{
setFile(filename);
@@ -145,8 +182,8 @@
auto it = sections.find(s);
if (it == sections.end())
{
- std::tie(it, std::ignore) =
- sections.emplace(Section(s), KeyValuesMapList{});
+ std::tie(it, std::ignore) = sections.emplace(
+ Section(Section::unchecked(), s), KeyValuesMapList{});
}
section = &it->second.emplace_back();
}
@@ -181,9 +218,10 @@
auto it = section->find(k);
if (it == section->end())
{
- std::tie(it, std::ignore) = section->emplace(Key(k), ValueList{});
+ std::tie(it, std::ignore) =
+ section->emplace(Key(Key::unchecked(), k), ValueList{});
}
- it->second.emplace_back(v);
+ it->second.emplace_back(Value::unchecked(), v);
}
void pump(std::string_view line)