in src/modules/compliance/src/lib/Procedure.cpp [101:185]
Optional<Error> Procedure::UpdateUserParameters(const std::string& input)
{
size_t pos = 0;
while (pos < input.size())
{
// Skip spaces
pos = SkipSpaces(input, pos);
if (pos >= input.size())
{
break;
}
// Parse key
const size_t keyStart = pos;
auto result = ParseKey(input, pos);
if (!result.HasValue())
{
return result.Error();
}
pos = result.Value();
if (keyStart == pos)
{
return Error("Invalid key-value pair: empty key");
}
auto key = input.substr(keyStart, pos - keyStart);
if ((pos >= input.size()) || (input[pos] != '='))
{
return Error("Invalid key-value pair: '=' expected");
}
pos++; // Move past assignment character
if (pos >= input.size() || isspace(input[pos]))
{
return Error("Invalid key-value pair: missing value");
}
// Parse value
std::string value;
if ((input[pos] == '"') || (input[pos] == '\''))
{
const size_t valueStart = pos;
pos = ParseQuotedValue(input, pos, value);
// Check if the pos points past a proper quote
if (input[pos - 1] != input[valueStart])
{
return Error("Invalid key-value pair: missing closing quote or invalid escape sequence");
}
// If at the end of the input, we need to check if a closing quote was found, e.g.:
// k1=" should fail (ParseQuotedValue will terminate at the opening quote and return valueStart+1)
if ((pos >= input.size()) && (pos - valueStart == 1))
{
return Error("Invalid key-value pair: missing closing quote at the end of the input");
}
// We want to have at least one space after the value, e.g.:
// k1="1"k2="v2" should fail
if ((pos < input.size()) && (!isspace(input[pos])))
{
return Error("Invalid key-value pair: space expected after quoted value");
}
}
else
{
// Unquoted value
const size_t valueStart = pos;
while (pos < input.size() && !isspace(input[pos]))
{
pos++;
}
value = input.substr(valueStart, pos - valueStart);
}
auto it = mParameters.find(key);
if (it == mParameters.end())
{
return Error(std::string("User parameter '") + key + std::string("' not found"));
}
it->second = value;
}
return Optional<Error>();
}