From 13ad6e695f9ffc7847b3afe3e9cbcea8fb3a443f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 21 Oct 2020 13:36:35 +0000 Subject: [PATCH] networks: Improve parsing IP addresses loc_network_new_from_string() seem to have had some unexpected behaviour for invalid inputs. The function has been tidied up slightly and returns as soon as some invalid input was detected. Signed-off-by: Michael Tremer --- src/network.c | 52 +++++++++++++++++++++++++++++++--------------- src/test-network.c | 7 +++++++ 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/network.c b/src/network.c index 366caa2..c112a41 100644 --- a/src/network.c +++ b/src/network.c @@ -160,9 +160,10 @@ LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network LOC_EXPORT int loc_network_new_from_string(struct loc_ctx* ctx, struct loc_network** network, const char* address_string) { struct in6_addr first_address; - unsigned int prefix = 0; char* prefix_string; - int r = 1; + int r = -EINVAL; + + DEBUG(ctx, "Attempting to parse network %s\n", address_string); // Make a copy of the string to work on it char* buffer = strdup(address_string); @@ -171,29 +172,46 @@ LOC_EXPORT int loc_network_new_from_string(struct loc_ctx* ctx, struct loc_netwo // Split address and prefix address_string = strsep(&prefix_string, "/"); - // Did we find a prefix? - if (prefix_string) { - // Convert prefix to integer - prefix = strtol(prefix_string, NULL, 10); + DEBUG(ctx, " Split into address = %s, prefix = %s\n", address_string, prefix_string); - if (prefix) { - // Parse the address - r = loc_parse_address(ctx, address_string, &first_address); + // We need to have a prefix + if (!prefix_string) { + DEBUG(ctx, "No prefix set\n"); + goto FAIL; + } - // Map the prefix to IPv6 if needed - if (IN6_IS_ADDR_V4MAPPED(&first_address)) - prefix += 96; - } + // Convert prefix to integer + unsigned int prefix = strtol(prefix_string, NULL, 10); + + // End if the prefix was invalid + if (!prefix) { + DEBUG(ctx, "The prefix is zero or not a number\n"); + goto FAIL; + } + + // Parse the address + r = loc_parse_address(ctx, address_string, &first_address); + if (r) { + DEBUG(ctx, "The address could not be parsed\n"); + goto FAIL; } + // Map the prefix to IPv6 if needed + if (IN6_IS_ADDR_V4MAPPED(&first_address)) + prefix += 96; + +FAIL: // Free temporary buffer free(buffer); - if (r == 0) { - r = loc_network_new(ctx, network, &first_address, prefix); - } + // Exit if the parsing was unsuccessful + if (r) + return r; + + DEBUG(ctx, "GOT HERE\n"); - return r; + // Create a new network + return loc_network_new(ctx, network, &first_address, prefix); } LOC_EXPORT struct loc_network* loc_network_ref(struct loc_network* network) { diff --git a/src/test-network.c b/src/test-network.c index e908b57..85eca00 100644 --- a/src/test-network.c +++ b/src/test-network.c @@ -168,6 +168,13 @@ int main(int argc, char** argv) { exit(EXIT_FAILURE); } + // Try adding a single address + err = loc_writer_add_network(writer, &network, "2001:db8::"); + if (err != -EINVAL) { + fprintf(stderr, "It was possible to add an invalid network (err = %d)\n", err); + exit(EXIT_FAILURE); + } + FILE* f = tmpfile(); if (!f) { fprintf(stderr, "Could not open file for writing: %s\n", strerror(errno)); -- 2.39.2