mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Fix incorrect error message for duplicate options in configuration files.
Duplicating a non-multi-value option was not throwing the correct message when the option was a boolean. The reason was that the option was being validated as a boolean before the multi-value check was being done. The validation code assumed it was operating on a string but was instead operating on a string list causing an assertion to fail. Since it's not safe to do the multi-value check so late, move it up to the command-line and configuration file parse phases instead. Reported by Jesper St John.
This commit is contained in:
parent
be2271f6d3
commit
5404628148
@ -23,6 +23,14 @@
|
||||
<p>Fix missing missing URI encoding in S3 driver.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-ideator id="jesper.st.john"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Fix incorrect error message for duplicate options in configuration files.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Fix incorrectly reported error return in <id>info</id> logging. A return code of 1 from the <cmd>archive-get</cmd> was being logged as an error message at <id>info</id> level but otherwise worked correctly.</p>
|
||||
</release-item>
|
||||
|
@ -507,8 +507,12 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and reset", cfgOptionName(optionId));
|
||||
|
||||
// Add the argument
|
||||
if (optionList[optionListIdx].has_arg == required_argument)
|
||||
if (optionList[optionListIdx].has_arg == required_argument &&
|
||||
cfgDefOptionMulti(cfgOptionDefIdFromId(optionId)))
|
||||
{
|
||||
strLstAdd(parseOptionList[optionId].valueList, strNew(optarg));
|
||||
}
|
||||
// Error if the option does not accept multiple arguments
|
||||
else
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set multiple times", cfgOptionName(optionId));
|
||||
}
|
||||
@ -759,8 +763,16 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
parseOptionList[optionId].found = true;
|
||||
parseOptionList[optionId].source = cfgSourceConfig;
|
||||
|
||||
// Convert boolean to string
|
||||
if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
if (varType(value) == varTypeVariantList)
|
||||
{
|
||||
// Error if the option cannot be specified multiple times
|
||||
if (!cfgDefOptionMulti(optionDefId))
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set multiple times", cfgOptionName(optionId));
|
||||
|
||||
parseOptionList[optionId].valueList = strLstNewVarLst(varVarLst(value));
|
||||
}
|
||||
// Convert boolean
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
{
|
||||
if (strcasecmp(strPtr(varStr(value)), "n") == 0)
|
||||
parseOptionList[optionId].negate = true;
|
||||
@ -768,14 +780,11 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
THROW_FMT(OptionInvalidValueError, "boolean option '%s' must be 'y' or 'n'", strPtr(key));
|
||||
}
|
||||
// Else add the string value
|
||||
else if (varType(value) == varTypeString)
|
||||
else
|
||||
{
|
||||
parseOptionList[optionId].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[optionId].valueList, varStr(value));
|
||||
}
|
||||
// Else add the string list
|
||||
else
|
||||
parseOptionList[optionId].valueList = strLstNewVarLst(varVarLst(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -802,13 +811,6 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
cfgCommandName(cfgCommand()));
|
||||
}
|
||||
|
||||
// Error if this option does not allow multiple arguments
|
||||
if (parseOption->valueList != NULL && strLstSize(parseOption->valueList) > 1 &&
|
||||
!cfgDefOptionMulti(cfgOptionDefIdFromId(optionId)))
|
||||
{
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot have multiple arguments", cfgOptionName(optionId));
|
||||
}
|
||||
|
||||
// Is the option valid for this command? If not, there is nothing more to do.
|
||||
cfgOptionValidSet(optionId, cfgDefOptionValid(commandDefId, optionDefId));
|
||||
|
||||
|
@ -646,7 +646,7 @@ testRun(void)
|
||||
strLstAdd(argList, strNew("--compress-level=3"));
|
||||
TEST_ERROR(
|
||||
configParse(strLstSize(argList), strLstPtr(argList), false), OptionInvalidError,
|
||||
"option 'compress-level' cannot have multiple arguments");
|
||||
"option 'compress-level' cannot be set multiple times");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstNew();
|
||||
@ -966,7 +966,19 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(configParse(strLstSize(argList), strLstPtr(argList), false),
|
||||
OptionInvalidError,
|
||||
"option 'pg1-path' cannot have multiple arguments");
|
||||
"option 'pg1-path' cannot be set multiple times");
|
||||
|
||||
// Also test with a boolean option since this gets converted immediately and will blow up if it is multi
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageLocalWrite(), configFile),
|
||||
bufNewZ(
|
||||
"[db]\n"
|
||||
"start-fast=y\n"
|
||||
"start-fast=n\n"));
|
||||
|
||||
TEST_ERROR(configParse(strLstSize(argList), strLstPtr(argList), false),
|
||||
OptionInvalidError,
|
||||
"option 'start-fast' cannot be set multiple times");
|
||||
|
||||
// Test that log levels are set correctly when reset is enabled, then set them back to harness defaults
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user