Skip to content

Commit 5701ff8

Browse files
authored
Merge pull request #1195 from itsneufox/env-vars-patch
Patch to fix env vars
2 parents 3c308a3 + f4fa757 commit 5701ff8

File tree

1 file changed

+82
-22
lines changed

1 file changed

+82
-22
lines changed

Server/Source/core_impl.hpp

Lines changed: 82 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,15 @@ class Config final : public IEarlyConfig
320320

321321
std::map<String, ConfigStorage> defaults;
322322

323-
String expandEnvironmentVariables(const String& value) const
323+
String expandEnvironmentVariablesInRawJSON(const String& jsonText) const
324324
{
325325
String result;
326-
result.reserve(value.length());
326+
result.reserve(jsonText.length());
327327

328328
size_t i = 0;
329-
while (i < value.length())
329+
while (i < jsonText.length())
330330
{
331-
const char ch = value[i];
331+
const char ch = jsonText[i];
332332

333333
if (ch != '$')
334334
{
@@ -337,46 +337,43 @@ class Config final : public IEarlyConfig
337337
continue;
338338
}
339339

340-
if (i + 1 < value.length() && value[i + 1] == '$')
340+
if (i + 1 < jsonText.length() && jsonText[i + 1] == '$')
341341
{
342342
result.push_back('$');
343343
i += 2;
344344
continue;
345345
}
346346

347-
if (i + 1 >= value.length() || value[i + 1] != '{')
347+
if (i + 1 >= jsonText.length() || jsonText[i + 1] != '{')
348348
{
349349
result.push_back(ch);
350350
++i;
351351
continue;
352352
}
353353

354354
const size_t varStart = i + 2;
355-
const size_t end = value.find('}', varStart);
355+
const size_t end = jsonText.find('}', varStart);
356356

357357
if (end == String::npos)
358358
{
359-
result.append(value.substr(i));
359+
result.append(jsonText.substr(i));
360360
break;
361361
}
362362

363-
const String fullVar = value.substr(varStart, end - varStart);
363+
const String fullVar = jsonText.substr(varStart, end - varStart);
364364
const size_t defaultPos = fullVar.find(":-");
365365

366366
const String varName = (defaultPos != String::npos) ? fullVar.substr(0, defaultPos) : fullVar;
367+
const String defaultValue = (defaultPos != String::npos) ? fullVar.substr(defaultPos + 2) : "";
367368
const char* envValue = std::getenv(varName.c_str());
368369

369-
if (envValue)
370+
if (envValue && envValue[0] != '\0')
370371
{
371372
result.append(envValue);
372373
}
373-
else if (defaultPos != String::npos)
374+
else if (!defaultValue.empty())
374375
{
375-
result.append(fullVar.substr(defaultPos + 2));
376-
}
377-
else
378-
{
379-
result.append(value.substr(i, end - i + 1));
376+
result.append(defaultValue);
380377
}
381378

382379
i = end + 1;
@@ -405,8 +402,7 @@ class Config final : public IEarlyConfig
405402
}
406403
else if (v.is_string())
407404
{
408-
String strValue = v.get<String>();
409-
processed[key].emplace<String>(expandEnvironmentVariables(strValue));
405+
processed[key].emplace<String>(v.get<String>());
410406
}
411407
else if (v.is_array())
412408
{
@@ -416,8 +412,7 @@ class Config final : public IEarlyConfig
416412
{
417413
if (arrVal.is_string())
418414
{
419-
String strValue = arrVal.get<String>();
420-
vec.emplace_back(expandEnvironmentVariables(strValue));
415+
vec.emplace_back(arrVal.get<String>());
421416
}
422417
}
423418
}
@@ -445,7 +440,10 @@ class Config final : public IEarlyConfig
445440
nlohmann::json props;
446441
try
447442
{
448-
props = nlohmann::json::parse(ifs, nullptr, true /* allow_exceptions */, true /* ignore_comments */);
443+
String fileContent((std::istreambuf_iterator<char>(ifs)),
444+
std::istreambuf_iterator<char>());
445+
String expandedContent = expandEnvironmentVariablesInRawJSON(fileContent);
446+
props = nlohmann::json::parse(expandedContent, nullptr, true /* allow_exceptions */, true /* ignore_comments */);
449447
}
450448
catch (nlohmann::json::exception const& e)
451449
{
@@ -475,14 +473,76 @@ class Config final : public IEarlyConfig
475473

476474
// Fill any values missing in config with defaults.
477475
// Fill default value if invalid type is provided.
476+
// if the user provided a string but expected type is different
477+
// attempt to parse string to the expected type.
478478
for (const auto& kv : Defaults)
479479
{
480480
auto itr = processed.find(kv.first);
481481
if (itr != processed.end())
482482
{
483483
if (itr->second.index() != kv.second.index())
484484
{
485-
itr->second = kv.second;
485+
// check if we can convert from string
486+
bool converted = false;
487+
if (itr->second.index() == 1) // User value is String
488+
{
489+
const String& strVal = std::get<String>(itr->second);
490+
switch (kv.second.index())
491+
{
492+
case 0: // Expected int
493+
{
494+
try
495+
{
496+
size_t pos = 0;
497+
int intVal = std::stoi(strVal, &pos);
498+
if (pos == strVal.length())
499+
{
500+
itr->second = intVal;
501+
converted = true;
502+
}
503+
}
504+
catch (...)
505+
{
506+
}
507+
break;
508+
}
509+
case 2: // Expected float
510+
{
511+
try
512+
{
513+
size_t pos = 0;
514+
float floatVal = std::stof(strVal, &pos);
515+
if (pos == strVal.length())
516+
{
517+
itr->second = floatVal;
518+
converted = true;
519+
}
520+
}
521+
catch (...)
522+
{
523+
}
524+
break;
525+
}
526+
case 4: // Expected bool
527+
{
528+
if (strVal == "true" || strVal == "1")
529+
{
530+
itr->second = true;
531+
converted = true;
532+
}
533+
else if (strVal == "false" || strVal == "0")
534+
{
535+
itr->second = false;
536+
converted = true;
537+
}
538+
break;
539+
}
540+
}
541+
}
542+
if (!converted)
543+
{
544+
itr->second = kv.second;
545+
}
486546
}
487547
continue;
488548
}

0 commit comments

Comments
 (0)