diff options
author | Martin Willi <martin@revosec.ch> | 2014-05-16 11:57:54 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-05-16 15:42:07 +0200 |
commit | 064fe9c963b7aa0ea904ab15443198d965175461 (patch) | |
tree | baafea8cdeb46701d996a07fa2bbb2c54fdf3458 /src | |
parent | 9ee8b3b41f9dd24e49f4fd80c5891f134b38d161 (diff) | |
download | strongswan-064fe9c963b7aa0ea904ab15443198d965175461.tar.bz2 strongswan-064fe9c963b7aa0ea904ab15443198d965175461.tar.xz |
enum: Return boolean result for enum_from_name() lookup
Handling the result for enum_from_name() is difficult, as checking for
negative return values requires a cast if the enum type is unsigned. The new
signature clearly differentiates lookup result from lookup value.
Further, this actually allows to convert real -1 enum values, which could not
be distinguished from "not-found" and the -1 return value.
This also fixes several clang warnings where enums are unsigned.
Diffstat (limited to 'src')
27 files changed, 101 insertions, 83 deletions
diff --git a/src/charon-cmd/cmd/cmd_connection.c b/src/charon-cmd/cmd/cmd_connection.c index ac085e131..c4c8a2a96 100644 --- a/src/charon-cmd/cmd/cmd_connection.c +++ b/src/charon-cmd/cmd/cmd_connection.c @@ -460,10 +460,9 @@ static void add_ts(private_cmd_connection_t *this, */ static void set_profile(private_cmd_connection_t *this, char *name) { - int profile; + profile_t profile; - profile = enum_from_name(profile_names, name); - if (profile == -1) + if (!enum_from_name(profile_names, name, &profile)) { DBG1(DBG_CFG, "unknown connection profile: %s", name); exit(1); diff --git a/src/conftest/hooks/add_notify.c b/src/conftest/hooks/add_notify.c index 9611cad6c..504b02a7b 100644 --- a/src/conftest/hooks/add_notify.c +++ b/src/conftest/hooks/add_notify.c @@ -73,8 +73,7 @@ METHOD(listener_t, message, bool, type = atoi(this->type); if (!type) { - type = enum_from_name(notify_type_names, this->type); - if (type == -1) + if (!enum_from_name(notify_type_names, this->type, &type)) { DBG1(DBG_CFG, "unknown notify: '%s', skipped", this->type); return TRUE; diff --git a/src/conftest/hooks/add_payload.c b/src/conftest/hooks/add_payload.c index 2903bb20f..cb5be1aef 100644 --- a/src/conftest/hooks/add_payload.c +++ b/src/conftest/hooks/add_payload.c @@ -77,8 +77,7 @@ METHOD(listener_t, message, bool, type = atoi(this->type); if (!type) { - type = enum_from_name(payload_type_short_names, this->type); - if (type == -1) + if (!enum_from_name(payload_type_short_names, this->type, &type)) { DBG1(DBG_CFG, "unknown payload: '%s', skipped", this->type); return TRUE; diff --git a/src/conftest/hooks/custom_proposal.c b/src/conftest/hooks/custom_proposal.c index 38d4286c4..6086d13b5 100644 --- a/src/conftest/hooks/custom_proposal.c +++ b/src/conftest/hooks/custom_proposal.c @@ -79,8 +79,7 @@ static linked_list_t* load_proposals(private_custom_proposal_t *this, type = strtoul(key, &end, 10); if (end == key || errno) { - type = enum_from_name(transform_type_names, key); - if (type == -1) + if (!enum_from_name(transform_type_names, key, &type)) { DBG1(DBG_CFG, "unknown transform: '%s', skipped", key); continue; diff --git a/src/conftest/hooks/set_critical.c b/src/conftest/hooks/set_critical.c index 8ec84e13d..15c313c51 100644 --- a/src/conftest/hooks/set_critical.c +++ b/src/conftest/hooks/set_critical.c @@ -65,8 +65,7 @@ METHOD(listener_t, message, bool, type = atoi(name); if (!type) { - type = enum_from_name(payload_type_short_names, name); - if (type == -1) + if (!enum_from_name(payload_type_short_names, name, &type)) { DBG1(DBG_CFG, "invalid payload name '%s'", name); break; diff --git a/src/conftest/hooks/set_length.c b/src/conftest/hooks/set_length.c index c1a867a99..b1a1a4723 100644 --- a/src/conftest/hooks/set_length.c +++ b/src/conftest/hooks/set_length.c @@ -63,8 +63,7 @@ METHOD(listener_t, message, bool, type = atoi(this->type); if (!type) { - type = enum_from_name(payload_type_short_names, this->type); - if (type == -1) + if (!enum_from_name(payload_type_short_names, this->type, &type)) { DBG1(DBG_CFG, "unknown payload: '%s', skipped", this->type); return TRUE; diff --git a/src/conftest/hooks/set_reserved.c b/src/conftest/hooks/set_reserved.c index d1a4a977b..5961aebc4 100644 --- a/src/conftest/hooks/set_reserved.c +++ b/src/conftest/hooks/set_reserved.c @@ -181,8 +181,7 @@ METHOD(listener_t, message, bool, type = atoi(name); if (!type) { - type = enum_from_name(payload_type_short_names, name); - if (type == -1) + if (!enum_from_name(payload_type_short_names, name, &type)) { DBG1(DBG_CFG, "invalid payload name '%s'", name); break; diff --git a/src/conftest/hooks/unencrypted_notify.c b/src/conftest/hooks/unencrypted_notify.c index f4c35725c..dae76faba 100644 --- a/src/conftest/hooks/unencrypted_notify.c +++ b/src/conftest/hooks/unencrypted_notify.c @@ -68,8 +68,7 @@ METHOD(listener_t, ike_updown, bool, type = atoi(this->type); if (!type) { - type = enum_from_name(notify_type_names, this->type); - if (type == -1) + if (!enum_from_name(notify_type_names, this->type, &type)) { DBG1(DBG_CFG, "unknown notify: '%s', skipped", this->type); return TRUE; diff --git a/src/conftest/hooks/unsort_message.c b/src/conftest/hooks/unsort_message.c index 1b2b302af..399d2932a 100644 --- a/src/conftest/hooks/unsort_message.c +++ b/src/conftest/hooks/unsort_message.c @@ -69,8 +69,7 @@ METHOD(listener_t, message, bool, order = enumerator_create_token(this->order, ", ", " "); while (order->enumerate(order, &name)) { - type = enum_from_name(payload_type_short_names, name); - if (type != -1) + if (enum_from_name(payload_type_short_names, name, &type)) { enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &payload)) diff --git a/src/libcharon/plugins/coupling/coupling_validator.c b/src/libcharon/plugins/coupling/coupling_validator.c index fc35462e3..0686e0f31 100644 --- a/src/libcharon/plugins/coupling/coupling_validator.c +++ b/src/libcharon/plugins/coupling/coupling_validator.c @@ -202,6 +202,7 @@ METHOD(coupling_validator_t, destroy, void, coupling_validator_t *coupling_validator_create() { private_coupling_validator_t *this; + hash_algorithm_t alg; char *path, *hash; INIT(this, @@ -219,8 +220,13 @@ coupling_validator_t *coupling_validator_create() hash = lib->settings->get_str(lib->settings, "%s.plugins.coupling.hash", "sha1", lib->ns); - this->hasher = lib->crypto->create_hasher(lib->crypto, - enum_from_name(hash_algorithm_short_names, hash)); + if (!enum_from_name(hash_algorithm_short_names, hash, &alg)) + { + DBG1(DBG_CFG, "unknown coupling hash algorithm: %s", hash); + destroy(this); + return NULL; + } + this->hasher = lib->crypto->create_hasher(lib->crypto, alg); if (!this->hasher) { DBG1(DBG_CFG, "unsupported coupling hash algorithm: %s", hash); diff --git a/src/libcharon/plugins/eap_radius/eap_radius_forward.c b/src/libcharon/plugins/eap_radius/eap_radius_forward.c index 54d52a98c..a41d5207d 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_forward.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_forward.c @@ -362,8 +362,7 @@ static linked_list_t* parse_selector(char *selector) vendor = atoi(token); token = pos; } - type = enum_from_name(radius_attribute_type_names, token); - if (type == -1) + if (!enum_from_name(radius_attribute_type_names, token, &type)) { type = atoi(token); } diff --git a/src/libcharon/plugins/load_tester/load_tester_creds.c b/src/libcharon/plugins/load_tester/load_tester_creds.c index f17d41f46..8fbb611db 100644 --- a/src/libcharon/plugins/load_tester/load_tester_creds.c +++ b/src/libcharon/plugins/load_tester/load_tester_creds.c @@ -465,7 +465,6 @@ load_tester_creds_t *load_tester_creds_create() .private = load_issuer_key(), .ca = load_issuer_cert(), .cas = linked_list_create(), - .digest = enum_from_name(hash_algorithm_short_names, digest), .psk = shared_key_create(SHARED_IKE, chunk_clone(chunk_create(psk, strlen(psk)))), .pwd = shared_key_create(SHARED_EAP, @@ -477,7 +476,7 @@ load_tester_creds_t *load_tester_creds_create() this->cas->insert_last(this->cas, this->ca->get_ref(this->ca)); } - if (this->digest == -1) + if (!enum_from_name(hash_algorithm_short_names, digest, &this->digest)) { DBG1(DBG_CFG, "invalid load-tester digest: '%s', using sha1", digest); this->digest = HASH_SHA1; @@ -487,4 +486,3 @@ load_tester_creds_t *load_tester_creds_create() return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 169ff2bf6..553a7cd12 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -584,8 +584,7 @@ static void stroke_loglevel(private_stroke_socket_t *this, } else { - group = enum_from_name(debug_names, msg->loglevel.type); - if ((int)group < 0) + if (!enum_from_name(debug_names, msg->loglevel.type, &group)) { fprintf(out, "unknown type '%s'!\n", msg->loglevel.type); return; diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index f89ae01a2..9a8e9a4d6 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -729,8 +729,7 @@ CALLBACK(list_certs, vici_message_t*, char *str; str = request->get_str(request, "ANY", "type"); - type = enum_from_name(certificate_type_names, str); - if (type == -1) + if (!enum_from_name(certificate_type_names, str, &type)) { b = vici_builder_create(); return b->finalize(b); diff --git a/src/libstrongswan/tests/suites/test_enum.c b/src/libstrongswan/tests/suites/test_enum.c index 512448a88..b48b51c0e 100644 --- a/src/libstrongswan/tests/suites/test_enum.c +++ b/src/libstrongswan/tests/suites/test_enum.c @@ -120,41 +120,50 @@ END_TEST */ static struct { + bool found; int val; char *str; } enum_tests_cont[] = { - {CONT1, "CONT1"}, - {CONT2, "CONT2"}, - {CONT2, "CoNt2"}, - {CONT3, "CONT3"}, - {CONT4, "CONT4"}, - {CONT5, "CONT5"}, - {-1, "asdf"}, - {-1, ""}, - {-1, NULL}, + {TRUE, CONT1, "CONT1"}, + {TRUE, CONT2, "CONT2"}, + {TRUE, CONT2, "CoNt2"}, + {TRUE, CONT3, "CONT3"}, + {TRUE, CONT4, "CONT4"}, + {TRUE, CONT5, "CONT5"}, + {FALSE, 0, "asdf"}, + {FALSE, 0, ""}, + {FALSE, 0, NULL}, }, enum_tests_split[] = { - {SPLIT1, "SPLIT1"}, - {SPLIT1, "split1"}, - {SPLIT2, "SPLIT2"}, - {SPLIT2, "SpLiT2"}, - {SPLIT3, "SPLIT3"}, - {SPLIT4, "SPLIT4"}, - {SPLIT5, "SPLIT5"}, - {-1, "asdf"}, - {-1, ""}, - {-1, NULL}, + {TRUE, SPLIT1, "SPLIT1"}, + {TRUE, SPLIT1, "split1"}, + {TRUE, SPLIT2, "SPLIT2"}, + {TRUE, SPLIT2, "SpLiT2"}, + {TRUE, SPLIT3, "SPLIT3"}, + {TRUE, SPLIT4, "SPLIT4"}, + {TRUE, SPLIT5, "SPLIT5"}, + {FALSE, 0, "asdf"}, + {FALSE, 0, ""}, + {FALSE, 0, NULL}, }; START_TEST(test_enum_from_name_cont) { - int val = enum_from_name(test_enum_cont_names, enum_tests_cont[_i].str); + int val = 0; + bool found; + + found = enum_from_name(test_enum_cont_names, enum_tests_cont[_i].str, &val); + ck_assert(enum_tests_cont[_i].found == found); ck_assert_int_eq(val, enum_tests_cont[_i].val); } END_TEST START_TEST(test_enum_from_name_split) { - int val = enum_from_name(test_enum_split_names, enum_tests_split[_i].str); + int val = 0; + bool found; + + found = enum_from_name(test_enum_split_names, enum_tests_split[_i].str, &val); + ck_assert(enum_tests_split[_i].found == found); ck_assert_int_eq(val, enum_tests_split[_i].val); } END_TEST diff --git a/src/libstrongswan/utils/enum.c b/src/libstrongswan/utils/enum.c index 465121e79..f96fe2989 100644 --- a/src/libstrongswan/utils/enum.c +++ b/src/libstrongswan/utils/enum.c @@ -40,7 +40,7 @@ char *enum_to_name(enum_name_t *e, int val) /** * See header. */ -int enum_from_name(enum_name_t *e, char *name) +bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val) { do { @@ -50,12 +50,13 @@ int enum_from_name(enum_name_t *e, char *name) { if (name && strcaseeq(name, e->names[i])) { - return e->first + i; + *val = e->first + i; + return TRUE; } } } while ((e = e->next)); - return -1; + return FALSE; } /** diff --git a/src/libstrongswan/utils/enum.h b/src/libstrongswan/utils/enum.h index a2f97d05e..a16485772 100644 --- a/src/libstrongswan/utils/enum.h +++ b/src/libstrongswan/utils/enum.h @@ -120,9 +120,30 @@ char *enum_to_name(enum_name_t *e, int val); * * @param e enum names for this enum value * @param name name to get enum value for - * @return enum value, -1 if not found + * @þaram valp variable sized pointer receiving value + * @return TRUE if enum name found, FALSE otherwise */ -int enum_from_name(enum_name_t *e, char *name); +#define enum_from_name(e, name, valp) ({ \ + int _val; \ + int _found = enum_from_name_as_int(e, name, &_val); \ + if (_found) \ + { \ + *(valp) = _val; \ + } \ + _found; }) + +/** + * Convert a enum string back to its enum value, integer pointer variant. + * + * This variant takes integer pointer only, use enum_from_name() to pass + * enum type pointers for the result. + * + * @param e enum names for this enum value + * @param name name to get enum value for + * @þaram val integer pointer receiving value + * @return TRUE if enum name found, FALSE otherwise + */ +bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val); /** * printf hook function for enum_names_t. diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 4f67b20d6..2cffeb820 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -959,8 +959,8 @@ static void filter_specific_config_suites(private_tls_crypto_t *this, enumerator = enumerator_create_token(config, ",", " "); while (enumerator->enumerate(enumerator, &token)) { - suite = enum_from_name(tls_cipher_suite_names, token); - if (suite == suites[i].suite) + if (enum_from_name(tls_cipher_suite_names, token, &suite) && + suite == suites[i].suite) { suites[remaining++] = suites[i]; break; diff --git a/src/libtnccs/plugins/tnc_imv/tnc_imv_manager.c b/src/libtnccs/plugins/tnc_imv/tnc_imv_manager.c index 56245015b..1a031582b 100644 --- a/src/libtnccs/plugins/tnc_imv/tnc_imv_manager.c +++ b/src/libtnccs/plugins/tnc_imv/tnc_imv_manager.c @@ -432,7 +432,7 @@ METHOD(imv_manager_t, destroy, void, imv_manager_t* tnc_imv_manager_create(void) { private_tnc_imv_manager_t *this; - recommendation_policy_t policy; + char *polname; INIT(this, .public = { @@ -458,11 +458,12 @@ imv_manager_t* tnc_imv_manager_create(void) .next_imv_id = 1, ); - policy = enum_from_name(recommendation_policy_names, - lib->settings->get_str(lib->settings, - "%s.plugins.tnc-imv.recommendation_policy", - "default", lib->ns)); - this->policy = (policy != -1) ? policy : RECOMMENDATION_POLICY_DEFAULT; + polname = lib->settings->get_str(lib->settings, + "%s.plugins.tnc-imv.recommendation_policy", "default", lib->ns); + if (!enum_from_name(recommendation_policy_names, polname, &this->policy)) + { + this->policy = RECOMMENDATION_POLICY_DEFAULT; + } DBG1(DBG_TNC, "TNC recommendation policy is '%N'", recommendation_policy_names, this->policy); diff --git a/src/libtnccs/plugins/tnccs_11/messages/tnccs_error_msg.c b/src/libtnccs/plugins/tnccs_11/messages/tnccs_error_msg.c index 86b7c6aa5..26a6c032f 100644 --- a/src/libtnccs/plugins/tnccs_11/messages/tnccs_error_msg.c +++ b/src/libtnccs/plugins/tnccs_11/messages/tnccs_error_msg.c @@ -128,9 +128,8 @@ tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node) error_type_name = xmlGetProp(node, "type"); if (error_type_name) { - this->error_type = enum_from_name(tnccs_error_type_names, - error_type_name); - if (this->error_type == -1) + if (!enum_from_name(tnccs_error_type_names, error_type_name, + &this->error_type)) { this->error_type = TNCCS_ERROR_OTHER; } diff --git a/src/libtnccs/plugins/tnccs_11/messages/tnccs_msg.c b/src/libtnccs/plugins/tnccs_11/messages/tnccs_msg.c index fa5ce8239..e3736560d 100644 --- a/src/libtnccs/plugins/tnccs_11/messages/tnccs_msg.c +++ b/src/libtnccs/plugins/tnccs_11/messages/tnccs_msg.c @@ -41,7 +41,7 @@ tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors) char *error_msg, buf[BUF_LEN]; tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH; tnccs_msg_t *msg; - tnccs_msg_type_t type = IMC_IMV_MSG; + tnccs_msg_type_t type = IMC_IMV_MSG, nametype; if (streq((char*)node->name, "IMC-IMV-Message")) { @@ -103,7 +103,8 @@ tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors) error_msg = "node is not in the TNCCS message namespace"; goto fatal; } - if (type != enum_from_name(tnccs_msg_type_names, (char*)cur->name)) + if (!enum_from_name(tnccs_msg_type_names, cur->name, &nametype) || + type != nametype) { error_msg = buf; snprintf(buf, BUF_LEN, "expected '%N' node but was '%s'", @@ -137,4 +138,3 @@ fatal: errors->insert_last(errors, msg); return NULL; } - diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c index d49365db5..4a11c4716 100644 --- a/src/pki/commands/acert.c +++ b/src/pki/commands/acert.c @@ -53,8 +53,7 @@ static int acert() case 'h': goto usage; case 'g': - digest = enum_from_name(hash_algorithm_short_names, arg); - if (digest == -1) + if (!enum_from_name(hash_algorithm_short_names, arg, &digest)) { error = "invalid --digest type"; goto usage; diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c index d03326e3d..339a88042 100644 --- a/src/pki/commands/issue.c +++ b/src/pki/commands/issue.c @@ -106,8 +106,7 @@ static int issue() } continue; case 'g': - digest = enum_from_name(hash_algorithm_short_names, arg); - if (digest == -1) + if (!enum_from_name(hash_algorithm_short_names, arg, &digest)) { error = "invalid --digest type"; goto usage; diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c index 5b2c128b7..1dce8cba2 100644 --- a/src/pki/commands/req.c +++ b/src/pki/commands/req.c @@ -64,8 +64,7 @@ static int req() } continue; case 'g': - digest = enum_from_name(hash_algorithm_short_names, arg); - if (digest == -1) + if (!enum_from_name(hash_algorithm_short_names, arg, &digest)) { error = "invalid --digest type"; goto usage; diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c index a35a42b89..80f5053a1 100644 --- a/src/pki/commands/self.c +++ b/src/pki/commands/self.c @@ -95,8 +95,7 @@ static int self() } continue; case 'g': - digest = enum_from_name(hash_algorithm_short_names, arg); - if (digest == -1) + if (!enum_from_name(hash_algorithm_short_names, arg, &digest)) { error = "invalid --digest type"; goto usage; diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index c9eebbf59..3be020a4c 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -142,8 +142,7 @@ static int sign_crl() case 'h': goto usage; case 'g': - digest = enum_from_name(hash_algorithm_short_names, arg); - if (digest == -1) + if (!enum_from_name(hash_algorithm_short_names, arg, &digest)) { error = "invalid --digest type"; goto usage; diff --git a/src/swanctl/commands/list_certs.c b/src/swanctl/commands/list_certs.c index d9b773892..6d7b6a938 100644 --- a/src/swanctl/commands/list_certs.c +++ b/src/swanctl/commands/list_certs.c @@ -556,10 +556,10 @@ CALLBACK(list_cb, void, bool has_privkey; buf = vici_find(res, &len, "data"); - type = enum_from_name(certificate_type_names, - vici_find_str(res, "ANY", "type")); has_privkey = streq(vici_find_str(res, "no", "has_privkey"), "yes"); - if (type != -1 && type != CERT_ANY && buf) + if (enum_from_name(certificate_type_names, + vici_find_str(res, "ANY", "type"), &type) && + type != CERT_ANY && buf) { cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, BUILD_BLOB_ASN1_DER, chunk_create(buf, len), |