nghttpx: Detect loop in --include paths
This commit is contained in:
parent
f96edbf987
commit
fb7775e382
19
src/shrpx.cc
19
src/shrpx.cc
|
@ -2030,11 +2030,13 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (conf_exists(get_config()->conf_path.get())) {
|
||||
if (load_config(get_config()->conf_path.get()) == -1) {
|
||||
std::set<std::string> include_set;
|
||||
if (load_config(get_config()->conf_path.get(), include_set) == -1) {
|
||||
LOG(FATAL) << "Failed to load configuration from "
|
||||
<< get_config()->conf_path.get();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
assert(include_set.empty());
|
||||
}
|
||||
|
||||
if (argc - optind >= 2) {
|
||||
|
@ -2046,11 +2048,18 @@ int main(int argc, char **argv) {
|
|||
// parsing option values.
|
||||
reopen_log_files();
|
||||
|
||||
for (size_t i = 0, len = cmdcfgs.size(); i < len; ++i) {
|
||||
if (parse_config(cmdcfgs[i].first, cmdcfgs[i].second) == -1) {
|
||||
LOG(FATAL) << "Failed to parse command-line argument.";
|
||||
exit(EXIT_FAILURE);
|
||||
{
|
||||
std::set<std::string> include_set;
|
||||
|
||||
for (size_t i = 0, len = cmdcfgs.size(); i < len; ++i) {
|
||||
if (parse_config(cmdcfgs[i].first, cmdcfgs[i].second, include_set) ==
|
||||
-1) {
|
||||
LOG(FATAL) << "Failed to parse command-line argument.";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
assert(include_set.empty());
|
||||
}
|
||||
|
||||
if (get_config()->accesslog_syslog || get_config()->errorlog_syslog) {
|
||||
|
|
|
@ -505,7 +505,8 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
int parse_config(const char *opt, const char *optarg) {
|
||||
int parse_config(const char *opt, const char *optarg,
|
||||
std::set<std::string> &included_set) {
|
||||
char host[NI_MAXHOST];
|
||||
uint16_t port;
|
||||
|
||||
|
@ -1220,7 +1221,20 @@ int parse_config(const char *opt, const char *optarg) {
|
|||
}
|
||||
|
||||
if (util::strieq(opt, SHRPX_OPT_INCLUDE)) {
|
||||
return load_config(optarg);
|
||||
if (included_set.count(optarg)) {
|
||||
LOG(ERROR) << opt << ": " << optarg << " has already been included";
|
||||
return -1;
|
||||
}
|
||||
|
||||
included_set.emplace(optarg);
|
||||
auto rv = load_config(optarg, included_set);
|
||||
included_set.erase(optarg);
|
||||
|
||||
if (rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (util::strieq(opt, "conf")) {
|
||||
|
@ -1234,7 +1248,7 @@ int parse_config(const char *opt, const char *optarg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int load_config(const char *filename) {
|
||||
int load_config(const char *filename, std::set<std::string> &include_set) {
|
||||
std::ifstream in(filename, std::ios::binary);
|
||||
if (!in) {
|
||||
LOG(ERROR) << "Could not open config file " << filename;
|
||||
|
@ -1258,7 +1272,7 @@ int load_config(const char *filename) {
|
|||
}
|
||||
line[i] = '\0';
|
||||
auto s = line.c_str();
|
||||
if (parse_config(s, s + i + 1) == -1) {
|
||||
if (parse_config(s, s + i + 1, include_set) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
|
@ -379,13 +380,16 @@ void create_config();
|
|||
|
||||
// Parses option name |opt| and value |optarg|. The results are
|
||||
// stored into statically allocated Config object. This function
|
||||
// returns 0 if it succeeds, or -1.
|
||||
int parse_config(const char *opt, const char *optarg);
|
||||
// returns 0 if it succeeds, or -1. The |included_set| contains the
|
||||
// all paths already included while processing this configuration, to
|
||||
// avoid loop in --include option.
|
||||
int parse_config(const char *opt, const char *optarg,
|
||||
std::set<std::string> &included_set);
|
||||
|
||||
// Loads configurations from |filename| and stores them in statically
|
||||
// allocated Config object. This function returns 0 if it succeeds, or
|
||||
// -1.
|
||||
int load_config(const char *filename);
|
||||
// -1. See parse_config() for |include_set|.
|
||||
int load_config(const char *filename, std::set<std::string> &include_set);
|
||||
|
||||
// Read passwd from |filename|
|
||||
std::string read_passwd_from_file(const char *filename);
|
||||
|
|
Loading…
Reference in New Issue