#include "maxminddb_test_helper.h" /* This test exercises a bug found in MMDB_get_value for certain types of * nested data structures which contain pointers. See * https://github.com/maxmind/libmaxminddb/issues/2 and * https://github.com/maxmind/libmaxminddb/issues/3. * * There is also the potential for a similar bug when looking up a value by * path in an array. This is not tested (yet) as we don't have the right test * data for it. * * These tests are somewhat fragile since they depend on a specific data * layout in the database. Ideally the test would check that this layout * exists before checking to see if the lookups are correct. */ void test_one_ip(MMDB_s *mmdb, const char *filename, const char *mode_desc, char *ip, char *country_code) { MMDB_lookup_result_s result = lookup_string_ok(mmdb, ip, filename, mode_desc); MMDB_entry_data_s entry_data = data_ok(&result, MMDB_DATA_TYPE_UTF8_STRING, "country{iso_code}", "country", "iso_code", NULL); if (ok(entry_data.has_data, "found data for country{iso_code}")) { char *string = mmdb_strndup(entry_data.utf8_string, entry_data.data_size); if (!string) { ok(0, "mmdb_strndup() call failed"); exit(1); } if (!ok(strcmp(string, country_code) == 0, "iso_code is %s", country_code)) { diag(" value is %s", string); } free(string); } } void run_tests(int mode, const char *mode_desc) { const char *filename = "GeoIP2-City-Test.mmdb"; const char *path = test_database_path(filename); MMDB_s *mmdb = open_ok(path, mode, mode_desc); free((void *)path); /* This exercises a bug where the entire top-level value is a pointer to * another part of the data section. */ test_one_ip(mmdb, filename, mode_desc, "2001:218::", "JP"); /* This exercises a bug where one subnet's data shares part of the data * with another subnet - in this case it is the "country" key (and others) * in the top level map. We are testing that the "country" key's value is * handled correctly. The value _should_ be a pointer to another map. */ test_one_ip(mmdb, filename, mode_desc, "81.2.69.160", "GB"); MMDB_close(mmdb); free(mmdb); } int main(void) { plan(NO_PLAN); for_all_modes(&run_tests); done_testing(); }