From b76e6d1a02c2c1779c205ab2383377ba77266f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 19 Nov 2019 13:32:48 +0100 Subject: [PATCH] loader: Handle unexpected error code from set_option() --- lib/loader/loader.c | 6 +++++ test/unittests/test_loader.cpp | 40 +++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/loader/loader.c b/lib/loader/loader.c index d820054..0cd4834 100644 --- a/lib/loader/loader.c +++ b/lib/loader/loader.c @@ -297,6 +297,12 @@ struct evmc_vm* evmc_load_and_configure(const char* config, enum evmc_loader_err "%s (%s): unsupported value '%s' for option '%s'", vm->name, path, option, name); goto exit; + + default: + ec = set_error(EVMC_LOADER_INVALID_OPTION_VALUE, + "%s (%s): unknown error when setting value '%s' for option '%s'", + vm->name, path, option, name); + goto exit; } } diff --git a/test/unittests/test_loader.cpp b/test/unittests/test_loader.cpp index e2cd3f7..82eeace 100644 --- a/test/unittests/test_loader.cpp +++ b/test/unittests/test_loader.cpp @@ -37,6 +37,7 @@ protected: static int destroy_count; static std::unordered_map> supported_options; static std::vector> recorded_options; + static const std::string option_name_causing_unknown_error; loader() noexcept { @@ -63,9 +64,18 @@ protected: if (it == supported_options.end()) return EVMC_SET_OPTION_INVALID_NAME; - const auto value_supported = - std::find(std::begin(it->second), std::end(it->second), value) != std::end(it->second); - return value_supported ? EVMC_SET_OPTION_SUCCESS : EVMC_SET_OPTION_INVALID_VALUE; + if (std::find(std::begin(it->second), std::end(it->second), value) != std::end(it->second)) + return EVMC_SET_OPTION_SUCCESS; + + if (name == option_name_causing_unknown_error) + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + return static_cast(-42); +#pragma GCC diagnostic pop + } + + return EVMC_SET_OPTION_INVALID_VALUE; } /// Creates a VM mock with only destroy() method. @@ -103,6 +113,9 @@ int loader::destroy_count = 0; std::unordered_map> loader::supported_options; std::vector> loader::recorded_options; +/// The option name that will return unexpected error code from the set_option() method. +const std::string loader::option_name_causing_unknown_error{"raise_unknown"}; + static evmc_vm* create_aaa() { return (evmc_vm*)0xaaa; @@ -625,4 +638,25 @@ TEST_F(loader, load_and_configure_error_not_wanted) EXPECT_EQ(destroy_count, create_count); EXPECT_STREQ(evmc_last_error_msg(), "vm_with_set_option (path): unknown option 'f'"); EXPECT_FALSE(evmc_last_error_msg()); +} + +TEST_F(loader, load_and_configure_unknown_set_option_error_code) +{ + // Enable "option name causing unknown error". + supported_options[option_name_causing_unknown_error] = {""}; + + setup("path", "evmc_create", create_vm_with_set_option); + + evmc_loader_error_code ec; + const auto config_str = "path," + option_name_causing_unknown_error + "=1"; + auto vm = evmc_load_and_configure(config_str.c_str(), &ec); + EXPECT_FALSE(vm); + ASSERT_EQ(recorded_options.size(), 1u); + EXPECT_EQ(recorded_options[0].first, option_name_causing_unknown_error); + EXPECT_EQ(recorded_options[0].second, "1"); + EXPECT_EQ(ec, EVMC_LOADER_INVALID_OPTION_VALUE); + EXPECT_EQ(evmc_last_error_msg(), + "vm_with_set_option (path): unknown error when setting value '1' for option '" + + option_name_causing_unknown_error + "'"); + EXPECT_EQ(destroy_count, create_count); } \ No newline at end of file