country: Add simple function to test if a country code is valid
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Oct 2019 13:40:02 +0000 (13:40 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Oct 2019 13:51:06 +0000 (13:51 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/database.c
src/loc/country.h
src/network.c
src/test-country.c

index 825d798..d19bf7c 100644 (file)
@@ -751,10 +751,6 @@ LOC_EXPORT int loc_database_enumerator_set_country_code(struct loc_database_enum
                return 0;
        }
 
-       // Country codes must be two characters
-       if (strlen(country_code) != 2)
-               return -EINVAL;
-
        // Treat A1, A2, A3 as special country codes,
        // but perform search for flags instead
        if (strcmp(country_code, "A1") == 0) {
@@ -768,6 +764,10 @@ LOC_EXPORT int loc_database_enumerator_set_country_code(struct loc_database_enum
                        LOC_NETWORK_FLAG_ANYCAST);
        }
 
+       // Country codes must be two characters
+       if (!loc_country_code_is_valid(country_code))
+               return -EINVAL;
+
        for (unsigned int i = 0; i < 3; i++) {
                enumerator->country_code[i] = country_code[i];
        }
index 8d4ab23..f650ade 100644 (file)
@@ -38,11 +38,32 @@ int loc_country_cmp(struct loc_country* country1, struct loc_country* country2);
 
 #ifdef LIBLOC_PRIVATE
 
+#include <string.h>
+
 int loc_country_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool,
                struct loc_country** country, const struct loc_database_country_v0* dbobj);
 int loc_country_to_database_v0(struct loc_country* country,
     struct loc_stringpool* pool, struct loc_database_country_v0* dbobj);
 
+static inline int loc_country_code_is_valid(const char* cc) {
+       // It cannot be NULL
+       if (!cc || !*cc)
+               return 0;
+
+       // It must be 2 characters long
+       if (strlen(cc) != 2)
+               return 0;
+
+       // It must only contain A-Z
+       for (unsigned int i = 0; i < 2; i++) {
+               if (cc[i] < 'A' || cc[i] > 'Z')
+                       return 0;
+       }
+
+       // Looks valid
+       return 1;
+}
+
 static inline void loc_country_copy_code(char* dst, const char* src) {
     for (unsigned int i = 0; i < 2; i++) {
         dst[i] = src[i];
index 182e0dd..387e18d 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include <loc/libloc.h>
+#include <loc/country.h>
 #include <loc/network.h>
 #include <loc/private.h>
 
@@ -295,8 +296,8 @@ LOC_EXPORT int loc_network_set_country_code(struct loc_network* network, const c
                return 0;
        }
 
-       // Country codes must be two characters
-       if (strlen(country_code) != 2)
+       // Check country code
+       if (!loc_country_code_is_valid(country_code))
                return -EINVAL;
 
        for (unsigned int i = 0; i < 3; i++) {
@@ -307,8 +308,8 @@ LOC_EXPORT int loc_network_set_country_code(struct loc_network* network, const c
 }
 
 LOC_EXPORT int loc_network_match_country_code(struct loc_network* network, const char* country_code) {
-       // Country codes must be two characters
-       if (strlen(country_code) != 2)
+       // Check country code
+       if (!loc_country_code_is_valid(country_code))
                return -EINVAL;
 
        return (network->country_code[0] == country_code[0])
index 96e1c3b..99516bb 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include <loc/libloc.h>
+#include <loc/country.h>
 #include <loc/database.h>
 #include <loc/network.h>
 #include <loc/writer.h>
@@ -29,6 +30,18 @@ int main(int argc, char** argv) {
        struct loc_country* country;
        int err;
 
+       // Check some valid country codes
+       if (!loc_country_code_is_valid("XX")) {
+               fprintf(stderr, "Valid country code detected as invalid: %s\n", "XX");
+               exit(EXIT_FAILURE);
+       }
+
+       // Check some invalid country codes
+       if (loc_country_code_is_valid("X1")) {
+               fprintf(stderr, "Invalid country code detected as valid: %s\n", "X1");
+               exit(EXIT_FAILURE);
+       }
+
        struct loc_ctx* ctx;
        err = loc_new(&ctx);
        if (err < 0)
@@ -41,7 +54,7 @@ int main(int argc, char** argv) {
                exit(EXIT_FAILURE);
 
        // Create a country
-       err = loc_writer_add_country(writer, &country, "T1");
+       err = loc_writer_add_country(writer, &country, "XX");
        if (err) {
                fprintf(stderr, "Could not create country\n");
                exit(EXIT_FAILURE);
@@ -49,7 +62,7 @@ int main(int argc, char** argv) {
 
        // Set name & continent
        loc_country_set_name(country, "Testistan");
-       loc_country_set_continent_code(country, "XX");
+       loc_country_set_continent_code(country, "YY");
 
        // Free country
        loc_country_unref(country);
@@ -84,9 +97,9 @@ int main(int argc, char** argv) {
        }
 
        // Lookup an address in the subnet
-       err = loc_database_get_country(db, &country, "T1");
+       err = loc_database_get_country(db, &country, "XX");
        if (err) {
-               fprintf(stderr, "Could not find country T1\n");
+               fprintf(stderr, "Could not find country XX\n");
                exit(EXIT_FAILURE);
        }
        loc_country_unref(country);