Skip to content

Commit 4e5cf6e

Browse files
committed
Post-fixes by Andrey Kravchenko: Move ENV/FILE parsing into a separate routine. Validate configuration key before value. Ensure the username/password is not specified multiple times.
1 parent 39fa5ef commit 4e5cf6e

File tree

1 file changed

+60
-48
lines changed

1 file changed

+60
-48
lines changed

src/jrd/replication/Config.cpp

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ using namespace Replication;
5252
namespace
5353
{
5454
const char* REPLICATION_CFGFILE = "replication.conf";
55-
constexpr const char* KEY_ENV = "env";
56-
constexpr const char* KEY_FILE = "file";
55+
constexpr const char* KEY_SUFFIX_ENV = "env";
56+
constexpr const char* KEY_SUFFIX_FILE = "file";
5757

5858
const ULONG DEFAULT_BUFFER_SIZE = 1024 * 1024; // 1 MB
5959
const ULONG DEFAULT_SEGMENT_SIZE = 16 * 1024 * 1024; // 16 MB
@@ -104,64 +104,76 @@ namespace
104104
status->setErrors(sv.value());
105105
}
106106

107-
void parseSyncReplica(const ConfigFile::Parameters& params, SyncReplica& output)
107+
void parseExternalValue(const string& key, const string& value, string& output)
108108
{
109-
for (const auto& el : params)
109+
const auto pos = key.rfind('_');
110+
if (pos == string::npos)
110111
{
111-
string key(el.name.c_str());
112-
string value(el.value);
112+
output = value.c_str();
113+
return;
114+
}
113115

114-
if (value.isEmpty())
115-
continue;
116+
string temp;
117+
const string key_source = key.substr(pos + 1);
118+
119+
if (key_source.equals(KEY_SUFFIX_ENV))
120+
{
121+
fb_utils::readenv(value.c_str(), temp);
122+
if (temp.isEmpty())
123+
configError("missing environment variable", key, value);
124+
}
125+
else if (key_source.equals(KEY_SUFFIX_FILE))
126+
{
127+
PathName filename = value.c_str();
128+
PathUtils::fixupSeparators(filename);
129+
if (PathUtils::isRelative(filename))
130+
filename = fb_utils::getPrefix(IConfigManager::DIR_CONF, filename.c_str());
116131

117-
auto pos = key.rfind('_');
118-
if (pos != string::npos)
132+
AutoPtr<FILE> file(os_utils::fopen(filename.c_str(), "rt"));
133+
if (!file)
134+
configError("missing or inaccessible file", key, filename.c_str());
135+
136+
// skip first empty lines
137+
do
119138
{
120-
const string key_source = key.substr(pos + 1);
139+
if (feof(file))
140+
break;
121141

122-
if (key_source.equals(KEY_ENV))
123-
{
124-
fb_utils::readenv(value.c_str(), value);
125-
if (value.isEmpty())
126-
configError("missing environment variable", output.database, value);
142+
if (!temp.LoadFromFile(file))
143+
break;
127144

128-
key = key.substr(0, pos);
129-
}
130-
else if (key_source.equals(KEY_FILE))
131-
{
132-
PathName filename = value.c_str();
133-
PathUtils::fixupSeparators(filename);
134-
if (PathUtils::isRelative(filename))
135-
filename = fb_utils::getPrefix(IConfigManager::DIR_CONF, filename.c_str());
136-
137-
AutoPtr<FILE> file(os_utils::fopen(filename.c_str(), "rt"));
138-
if (!file)
139-
configError("missing or inaccessible file", output.database, filename.c_str());
140-
141-
// skip first empty lines
142-
value = "";
143-
do
144-
{
145-
if (feof(file))
146-
break;
145+
temp.alltrim(" \t\r");
146+
} while (temp.isEmpty());
147147

148-
if (!value.LoadFromFile(file))
149-
break;
148+
if (temp.isEmpty())
149+
configError("empty file", key, filename.c_str());
150+
}
150151

151-
value.alltrim(" \t\r");
152-
} while (value.isEmpty());
152+
output = temp.c_str();
153+
}
153154

154-
if (value.isEmpty())
155-
configError("empty file", output.database, filename.c_str());
155+
void parseSyncReplica(const ConfigFile::Parameters& params, SyncReplica& output)
156+
{
157+
for (const auto& el : params)
158+
{
159+
const string key(el.name.c_str());
160+
const string value(el.value);
156161

157-
key = key.substr(0, pos);
158-
}
159-
}
162+
if (value.isEmpty())
163+
continue;
160164

161-
if (key == "username")
162-
output.username = value.c_str();
163-
else if (key == "password")
164-
output.password = value.c_str();
165+
if (key.find("username") == 0)
166+
{
167+
if (output.username.hasData())
168+
configError("multiple values", output.database, "username");
169+
parseExternalValue(key, value, output.username);
170+
}
171+
else if (key.find("password") == 0)
172+
{
173+
if (output.password.hasData())
174+
configError("multiple values", output.database, "password");
175+
parseExternalValue(key, value, output.password);
176+
}
165177
else
166178
configError("unknown parameter", output.database, key);
167179
}

0 commit comments

Comments
 (0)