diff --git a/apps/openmw_test_suite/openmw/options.cpp b/apps/openmw_test_suite/openmw/options.cpp index dacf9c81f3..33c38da5df 100644 --- a/apps/openmw_test_suite/openmw/options.cpp +++ b/apps/openmw_test_suite/openmw/options.cpp @@ -33,7 +33,7 @@ namespace std::vector result; (result.emplace_back(makeString(args)) , ...); for (int i = 1; i <= std::numeric_limits::max(); ++i) - if (i != '\\' && i != '"' && i != ' ' && i != '\n') + if (i != '&' && i != '"' && i != ' ' && i != '\n') result.push_back(std::string(1, i)); return result; } @@ -127,22 +127,22 @@ namespace EXPECT_EQ(variables["load-savegame"].as().string(), R"(save)"); } - TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_quote) + TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_quote_by_ampersand) { bpo::options_description description = makeOptionsDescription(); - const std::array arguments {"openmw", "--load-savegame", R"("save\".omwsave")"}; + const std::array arguments {"openmw", "--load-savegame", R"("save&".omwsave")"}; bpo::variables_map variables; parseArgs(arguments, variables, description); EXPECT_EQ(variables["load-savegame"].as().string(), R"(save".omwsave)"); } - TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_backslash) + TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_ampersand) { bpo::options_description description = makeOptionsDescription(); - const std::array arguments {"openmw", "--load-savegame", R"("save.omwsave\\")"}; + const std::array arguments {"openmw", "--load-savegame", R"("save.omwsave&&")"}; bpo::variables_map variables; parseArgs(arguments, variables, description); - EXPECT_EQ(variables["load-savegame"].as().string(), R"(save.omwsave\)"); + EXPECT_EQ(variables["load-savegame"].as().string(), "save.omwsave&"); } TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_ampersand) @@ -274,7 +274,7 @@ namespace TEST(OpenMWOptionsFromConfig, should_support_confusing_savegame_path_with_lots_going_on) { bpo::options_description description = makeOptionsDescription(); - std::istringstream stream(R"(load-savegame="one \"two"three".omwsave")"); + std::istringstream stream(R"(load-savegame="one &"two"three".omwsave")"); bpo::variables_map variables; Files::parseConfig(stream, variables, description); EXPECT_EQ(variables["load-savegame"].as().string(), R"(one "two)"); @@ -283,7 +283,7 @@ namespace TEST(OpenMWOptionsFromConfig, should_support_confusing_savegame_path_with_even_more_going_on) { bpo::options_description description = makeOptionsDescription(); - std::istringstream stream(R"(load-savegame="one \"two"three ".omwsave")"); + std::istringstream stream(R"(load-savegame="one &"two"three ".omwsave")"); bpo::variables_map variables; Files::parseConfig(stream, variables, description); EXPECT_EQ(variables["load-savegame"].as().string(), R"(one "two)"); @@ -351,22 +351,22 @@ namespace EXPECT_THAT(variables["data"].as(), ElementsAre(IsPath("1"), IsPath("2"))); } - TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_escaped_quote) + TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_escaped_quote_by_ampersand) { bpo::options_description description = makeOptionsDescription(); - std::istringstream stream(R"(load-savegame="save\".omwsave")"); + std::istringstream stream(R"(load-savegame="save&".omwsave")"); bpo::variables_map variables; Files::parseConfig(stream, variables, description); EXPECT_EQ(variables["load-savegame"].as().string(), R"(save".omwsave)"); } - TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_escaped_backslash) + TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_escaped_ampersand) { bpo::options_description description = makeOptionsDescription(); - std::istringstream stream(R"(load-savegame="save.omwsave\\")"); + std::istringstream stream(R"(load-savegame="save.omwsave&&")"); bpo::variables_map variables; Files::parseConfig(stream, variables, description); - EXPECT_EQ(variables["load-savegame"].as().string(), R"(save.omwsave\)"); + EXPECT_EQ(variables["load-savegame"].as().string(), "save.omwsave&"); } TEST(OpenMWOptionsFromConfig, should_support_load_savegame_path_with_ampersand) diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index f792af5f3d..37eca2c460 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -432,7 +432,9 @@ std::istream& operator>> (std::istream& istream, MaybeQuotedPath& MaybeQuotedPat // If it doesn't start with a double quote, read the whole thing verbatim if (istream.peek() == '"') { - istream >> static_cast(MaybeQuotedPath); + std::string intermediate; + istream >> std::quoted(intermediate, '"', '&'); + static_cast(MaybeQuotedPath) = intermediate; if (istream && !istream.eof() && istream.peek() != EOF) { std::string remainder{std::istreambuf_iterator(istream), {}};