2021-01-31 17:48:31 +01:00
|
|
|
#include "maxminddb_test_helper.h"
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_array_0_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_SUCCESS,
|
|
|
|
"status for %s() is MMDB_SUCCESS - array[0]",
|
|
|
|
function);
|
2021-01-31 17:48:31 +01:00
|
|
|
ok(entry_data.has_data, "found a value for array[0]");
|
2021-08-22 19:15:19 +02:00
|
|
|
cmp_ok(entry_data.type,
|
|
|
|
"==",
|
|
|
|
MMDB_DATA_TYPE_UINT32,
|
2021-01-31 17:48:31 +01:00
|
|
|
"returned entry type is uint32 - array[0]");
|
|
|
|
cmp_ok(entry_data.uint32, "==", 1, "entry value is 1 - array[0]");
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_array_2_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_SUCCESS,
|
|
|
|
"status for %s() is MMDB_SUCCESS - array[2]",
|
|
|
|
function);
|
2021-01-31 17:48:31 +01:00
|
|
|
ok(entry_data.has_data, "found a value for array[2]");
|
2021-08-22 19:15:19 +02:00
|
|
|
cmp_ok(entry_data.type,
|
|
|
|
"==",
|
|
|
|
MMDB_DATA_TYPE_UINT32,
|
2021-01-31 17:48:31 +01:00
|
|
|
"returned entry type is uint32 - array[2]");
|
|
|
|
cmp_ok(entry_data.uint32, "==", 3, "entry value is 3 - array[2]");
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_array_minus_3_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_SUCCESS,
|
|
|
|
"status for %s() is MMDB_SUCCESS - array[-3]",
|
|
|
|
function);
|
2021-01-31 17:48:31 +01:00
|
|
|
ok(entry_data.has_data, "found a value for array[-3]");
|
2021-08-22 19:15:19 +02:00
|
|
|
cmp_ok(entry_data.type,
|
|
|
|
"==",
|
|
|
|
MMDB_DATA_TYPE_UINT32,
|
2021-01-31 17:48:31 +01:00
|
|
|
"returned entry type is uint32 - array[-3]");
|
|
|
|
cmp_ok(entry_data.uint32, "==", 1, "entry value is 1 - array[-3]");
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_array_minus_1_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_SUCCESS,
|
|
|
|
"status for %s() is MMDB_SUCCESS - array[-1]",
|
|
|
|
function);
|
2021-01-31 17:48:31 +01:00
|
|
|
ok(entry_data.has_data, "found a value for array[-1]");
|
2021-08-22 19:15:19 +02:00
|
|
|
cmp_ok(entry_data.type,
|
|
|
|
"==",
|
|
|
|
MMDB_DATA_TYPE_UINT32,
|
2021-01-31 17:48:31 +01:00
|
|
|
"returned entry type is uint32 - array[-1]");
|
|
|
|
cmp_ok(entry_data.uint32, "==", 3, "entry value is 3 - array[-1]");
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
int call_vget_value(MMDB_entry_s *entry, MMDB_entry_data_s *entry_data, ...) {
|
2021-01-31 17:48:31 +01:00
|
|
|
va_list keys;
|
|
|
|
va_start(keys, entry_data);
|
|
|
|
|
|
|
|
int status = MMDB_vget_value(entry, entry_data, keys);
|
|
|
|
|
|
|
|
va_end(keys);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_simple_structure(int mode, const char *mode_desc) {
|
2021-01-31 17:48:31 +01:00
|
|
|
const char *filename = "MaxMind-DB-test-decoder.mmdb";
|
|
|
|
const char *path = test_database_path(filename);
|
|
|
|
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
|
|
|
free((void *)path);
|
|
|
|
|
|
|
|
const char *ip = "1.1.1.1";
|
|
|
|
MMDB_lookup_result_s result =
|
|
|
|
lookup_string_ok(mmdb, ip, filename, mode_desc);
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {"array", "0", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
|
|
|
test_array_0_result(status, entry_data, "MMDB_aget_value");
|
|
|
|
|
|
|
|
status = MMDB_get_value(&result.entry, &entry_data, "array", "0", NULL);
|
|
|
|
test_array_0_result(status, entry_data, "MMDB_get_value");
|
|
|
|
|
|
|
|
status =
|
|
|
|
call_vget_value(&result.entry, &entry_data, "array", "0", NULL);
|
|
|
|
test_array_0_result(status, entry_data, "MMDB_vget_value");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {"array", "2", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
|
|
|
test_array_2_result(status, entry_data, "MMDB_aget_value");
|
|
|
|
|
|
|
|
status = MMDB_get_value(&result.entry, &entry_data, "array", "2", NULL);
|
|
|
|
test_array_2_result(status, entry_data, "MMDB_get_value");
|
|
|
|
|
|
|
|
status =
|
|
|
|
call_vget_value(&result.entry, &entry_data, "array", "2", NULL);
|
|
|
|
test_array_2_result(status, entry_data, "MMDB_vget_value");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
int status =
|
|
|
|
MMDB_get_value(&result.entry, &entry_data, "array", "zero", NULL);
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR,
|
2021-01-31 17:48:31 +01:00
|
|
|
"MMDB_get_value() returns error on non-integer array index");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {"array", "-1", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
|
|
|
test_array_minus_1_result(status, entry_data, "MMDB_aget_value");
|
|
|
|
|
|
|
|
status =
|
|
|
|
MMDB_get_value(&result.entry, &entry_data, "array", "-1", NULL);
|
|
|
|
test_array_minus_1_result(status, entry_data, "MMDB_get_value");
|
|
|
|
|
|
|
|
status =
|
|
|
|
call_vget_value(&result.entry, &entry_data, "array", "-1", NULL);
|
|
|
|
test_array_minus_1_result(status, entry_data, "MMDB_vget_value");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {"array", "-3", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
|
|
|
test_array_minus_3_result(status, entry_data, "MMDB_aget_value");
|
|
|
|
|
|
|
|
status =
|
|
|
|
MMDB_get_value(&result.entry, &entry_data, "array", "-3", NULL);
|
|
|
|
test_array_minus_3_result(status, entry_data, "MMDB_get_value");
|
|
|
|
|
|
|
|
status =
|
|
|
|
call_vget_value(&result.entry, &entry_data, "array", "-3", NULL);
|
|
|
|
test_array_minus_3_result(status, entry_data, "MMDB_vget_value");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
int status =
|
|
|
|
MMDB_get_value(&result.entry, &entry_data, "array", "-4", NULL);
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR,
|
2021-01-31 17:48:31 +01:00
|
|
|
"MMDB_get_value() returns error on too large negative integer");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
int status = MMDB_get_value(
|
|
|
|
&result.entry, &entry_data, "array", "-18446744073709551616", NULL);
|
|
|
|
cmp_ok(
|
|
|
|
status,
|
|
|
|
"==",
|
|
|
|
MMDB_INVALID_LOOKUP_PATH_ERROR,
|
|
|
|
"MMDB_get_value() returns error on integer smaller than LONG_MIN");
|
2021-01-31 17:48:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
int status = MMDB_get_value(
|
|
|
|
&result.entry, &entry_data, "array", "18446744073709551616", NULL);
|
|
|
|
cmp_ok(
|
|
|
|
status,
|
|
|
|
"==",
|
|
|
|
MMDB_INVALID_LOOKUP_PATH_ERROR,
|
|
|
|
"MMDB_get_value() returns error on integer larger than LONG_MAX");
|
2021-01-31 17:48:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
MMDB_close(mmdb);
|
|
|
|
free(mmdb);
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_complex_map_a_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_SUCCESS,
|
2021-01-31 17:48:31 +01:00
|
|
|
"status for %s() is MMDB_SUCCESS - map1{map2}{array}[0]{map3}{a}",
|
|
|
|
function);
|
2021-08-22 19:15:19 +02:00
|
|
|
ok(entry_data.has_data, "found a value for map1{map2}{array}[0]{map3}{a}");
|
|
|
|
cmp_ok(entry_data.type,
|
|
|
|
"==",
|
|
|
|
MMDB_DATA_TYPE_UINT32,
|
2021-01-31 17:48:31 +01:00
|
|
|
"returned entry type is uint32 - map1{map2}{array}[0]{map3}{a}");
|
2021-08-22 19:15:19 +02:00
|
|
|
cmp_ok(entry_data.uint32,
|
|
|
|
"==",
|
|
|
|
1,
|
2021-01-31 17:48:31 +01:00
|
|
|
"entry value is 1 - map1{map2}{array}[0]{map3}{a}");
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_complex_map_c_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_SUCCESS,
|
|
|
|
"status for %s() is MMDB_SUCCESS - map1{map2}{array}[0]{map3}{c}",
|
|
|
|
function);
|
|
|
|
ok(entry_data.has_data, "found a value for map1{map2}{array}[0]{map3}{c}");
|
|
|
|
cmp_ok(entry_data.type,
|
|
|
|
"==",
|
|
|
|
MMDB_DATA_TYPE_UINT32,
|
2021-01-31 17:48:31 +01:00
|
|
|
"returned entry type is uint32 - map1{map2}{array}[0]{map3}{c}");
|
2021-08-22 19:15:19 +02:00
|
|
|
cmp_ok(entry_data.uint32,
|
|
|
|
"==",
|
|
|
|
3,
|
2021-01-31 17:48:31 +01:00
|
|
|
"entry value is 3 - map1{map2}{array}[0]{map3}{c}");
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_no_result(int status,
|
|
|
|
MMDB_entry_data_s entry_data,
|
|
|
|
char *function,
|
|
|
|
char *path_description) {
|
|
|
|
cmp_ok(status,
|
|
|
|
"==",
|
|
|
|
MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR,
|
2021-01-31 17:48:31 +01:00
|
|
|
"status for %s() is MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR - %s",
|
2021-08-22 19:15:19 +02:00
|
|
|
function,
|
|
|
|
path_description);
|
2021-01-31 17:48:31 +01:00
|
|
|
ok(!entry_data.has_data, "did not find a value for %s", path_description);
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_nested_structure(int mode, const char *mode_desc) {
|
2021-01-31 17:48:31 +01:00
|
|
|
const char *filename = "MaxMind-DB-test-nested.mmdb";
|
|
|
|
const char *path = test_database_path(filename);
|
|
|
|
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
|
|
|
free((void *)path);
|
|
|
|
|
|
|
|
const char *ip = "1.1.1.1";
|
|
|
|
MMDB_lookup_result_s result =
|
|
|
|
lookup_string_ok(mmdb, ip, filename, mode_desc);
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {
|
|
|
|
"map1", "map2", "array", "0", "map3", "a", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
|
|
|
test_complex_map_a_result(status, entry_data, "MMDB_aget_value");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = MMDB_get_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map2",
|
|
|
|
"array",
|
|
|
|
"0",
|
|
|
|
"map3",
|
|
|
|
"a",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
|
|
|
test_complex_map_a_result(status, entry_data, "MMDB_get_value");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = call_vget_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map2",
|
|
|
|
"array",
|
|
|
|
"0",
|
|
|
|
"map3",
|
|
|
|
"a",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
|
|
|
test_complex_map_a_result(status, entry_data, "MMDB_vget_value");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {
|
|
|
|
"map1", "map2", "array", "0", "map3", "c", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
|
|
|
test_complex_map_c_result(status, entry_data, "MMDB_aget_value");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = MMDB_get_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map2",
|
|
|
|
"array",
|
|
|
|
"0",
|
|
|
|
"map3",
|
|
|
|
"c",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
|
|
|
test_complex_map_c_result(status, entry_data, "MMDB_get_value");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = call_vget_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map2",
|
|
|
|
"array",
|
|
|
|
"0",
|
|
|
|
"map3",
|
|
|
|
"c",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
|
|
|
test_complex_map_c_result(status, entry_data, "MMDB_vget_value");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {
|
|
|
|
"map1", "map42", "array", "0", "map3", "c", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
2021-08-22 19:15:19 +02:00
|
|
|
test_no_result(status,
|
|
|
|
entry_data,
|
|
|
|
"MMDB_aget_value",
|
2021-01-31 17:48:31 +01:00
|
|
|
"map1{map42}{array}[0]{map3}{c}");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = MMDB_get_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map42",
|
|
|
|
"array",
|
|
|
|
"0",
|
|
|
|
"map3",
|
|
|
|
"c",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
2021-08-22 19:15:19 +02:00
|
|
|
test_no_result(status,
|
|
|
|
entry_data,
|
|
|
|
"MMDB_get_value",
|
2021-01-31 17:48:31 +01:00
|
|
|
"map1{map42}{array}[0]{map3}{c}");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = call_vget_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map42",
|
|
|
|
"array",
|
|
|
|
"0",
|
|
|
|
"map3",
|
|
|
|
"c",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
2021-08-22 19:15:19 +02:00
|
|
|
test_no_result(status,
|
|
|
|
entry_data,
|
|
|
|
"MMDB_vget_value",
|
2021-01-31 17:48:31 +01:00
|
|
|
"map1{map42}{array}[0]{map3}{c}");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MMDB_entry_data_s entry_data;
|
2021-08-22 19:15:19 +02:00
|
|
|
const char *lookup_path[] = {
|
|
|
|
"map1", "map2", "array", "9", "map3", "c", NULL};
|
2021-01-31 17:48:31 +01:00
|
|
|
int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
2021-08-22 19:15:19 +02:00
|
|
|
test_no_result(status,
|
|
|
|
entry_data,
|
|
|
|
"MMDB_aget_value",
|
2021-01-31 17:48:31 +01:00
|
|
|
"map1{map42}{array}[9]{map3}{c}");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = MMDB_get_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map2",
|
|
|
|
"array",
|
|
|
|
"9",
|
|
|
|
"map3",
|
|
|
|
"c",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
2021-08-22 19:15:19 +02:00
|
|
|
test_no_result(status,
|
|
|
|
entry_data,
|
|
|
|
"MMDB_get_value",
|
2021-01-31 17:48:31 +01:00
|
|
|
"map1{map42}{array}[9]{map3}{c}");
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
status = call_vget_value(&result.entry,
|
|
|
|
&entry_data,
|
|
|
|
"map1",
|
|
|
|
"map2",
|
|
|
|
"array",
|
|
|
|
"9",
|
|
|
|
"map3",
|
|
|
|
"c",
|
2021-01-31 17:48:31 +01:00
|
|
|
NULL);
|
2021-08-22 19:15:19 +02:00
|
|
|
test_no_result(status,
|
|
|
|
entry_data,
|
|
|
|
"MMDB_vget_value",
|
2021-01-31 17:48:31 +01:00
|
|
|
"map1{map42}{array}[9]{map3}{c}");
|
|
|
|
}
|
|
|
|
|
|
|
|
MMDB_close(mmdb);
|
|
|
|
free(mmdb);
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void run_tests(int mode, const char *mode_desc) {
|
2021-01-31 17:48:31 +01:00
|
|
|
test_simple_structure(mode, mode_desc);
|
|
|
|
test_nested_structure(mode, mode_desc);
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
int main(void) {
|
2021-01-31 17:48:31 +01:00
|
|
|
plan(NO_PLAN);
|
|
|
|
for_all_modes(&run_tests);
|
|
|
|
done_testing();
|
|
|
|
}
|