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